FIR: Remove FirQualifiedAcces.safe in non-generated code

^KT-38444 In Progress
This commit is contained in:
Denis Zharkov
2020-06-02 12:35:54 +03:00
parent 55a4c40970
commit 291afd8448
18 changed files with 11 additions and 70 deletions
@@ -1304,11 +1304,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
val explicitReceiver = access.explicitReceiver val explicitReceiver = access.explicitReceiver
if (explicitReceiver != null) { if (explicitReceiver != null) {
generate(explicitReceiver) generate(explicitReceiver)
if (access.safe) { +"."
+"?."
} else {
+"."
}
} }
} }
@@ -118,8 +118,6 @@ internal class CallAndReferenceGenerator(
typeRef: FirTypeRef, typeRef: FirTypeRef,
explicitReceiverExpression: IrExpression? explicitReceiverExpression: IrExpression?
): IrExpression { ): IrExpression {
require(!qualifiedAccess.safe)
val type = typeRef.toIrType() val type = typeRef.toIrType()
val samConstructorCall = qualifiedAccess.tryConvertToSamConstructorCall(type) val samConstructorCall = qualifiedAccess.tryConvertToSamConstructorCall(type)
if (samConstructorCall != null) return samConstructorCall if (samConstructorCall != null) return samConstructorCall
@@ -473,7 +473,6 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
val firMemberAccess = left.convertQualified() val firMemberAccess = left.convertQualified()
return if (firMemberAccess != null) { return if (firMemberAccess != null) {
explicitReceiver = firMemberAccess.explicitReceiver explicitReceiver = firMemberAccess.explicitReceiver
safe = firMemberAccess.safe
firMemberAccess.calleeReference firMemberAccess.calleeReference
} else { } else {
buildErrorNamedReference { buildErrorNamedReference {
@@ -546,7 +545,6 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
return buildVariableAssignment { return buildVariableAssignment {
source = baseSource source = baseSource
safe = false
rValue = value rValue = value
calleeReference = initializeLValue(this@generateAssignment) { convert() as? FirQualifiedAccess } calleeReference = initializeLValue(this@generateAssignment) { convert() as? FirQualifiedAccess }
} }
@@ -562,7 +560,6 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
val assignment = buildVariableAssignment { val assignment = buildVariableAssignment {
source = baseSource source = baseSource
safe = false
rValue = value rValue = value
calleeReference = nestedAccess.calleeReference calleeReference = nestedAccess.calleeReference
explicitReceiver = safeCallNonAssignment.checkedSubject.value explicitReceiver = safeCallNonAssignment.checkedSubject.value
@@ -1705,7 +1705,6 @@ class RawFirBuilder(
return firSelector.wrapWithSafeCall(receiver) return firSelector.wrapWithSafeCall(receiver)
} }
firSelector.safe = false
firSelector.explicitReceiver = receiver firSelector.explicitReceiver = receiver
} }
return firSelector return firSelector
@@ -32,7 +32,6 @@ fun FirFunctionCall.copy(
dispatchReceiver: FirExpression = this.dispatchReceiver, dispatchReceiver: FirExpression = this.dispatchReceiver,
extensionReceiver: FirExpression = this.extensionReceiver, extensionReceiver: FirExpression = this.extensionReceiver,
source: FirSourceElement? = this.source, source: FirSourceElement? = this.source,
safe: Boolean = this.safe,
typeArguments: List<FirTypeProjection> = this.typeArguments, typeArguments: List<FirTypeProjection> = this.typeArguments,
resultType: FirTypeRef = this.typeRef resultType: FirTypeRef = this.typeRef
): FirFunctionCall { ): FirFunctionCall {
@@ -47,7 +46,6 @@ fun FirFunctionCall.copy(
} }
builder.apply { builder.apply {
this.source = source this.source = source
this.safe = safe
this.annotations.addAll(annotations) this.annotations.addAll(annotations)
this.argumentList = argumentList this.argumentList = argumentList
this.explicitReceiver = explicitReceiver this.explicitReceiver = explicitReceiver
@@ -88,7 +88,6 @@ class FirCallResolver(
dispatchReceiver = candidate.dispatchReceiverExpression(), dispatchReceiver = candidate.dispatchReceiverExpression(),
extensionReceiver = candidate.extensionReceiverExpression(), extensionReceiver = candidate.extensionReceiverExpression(),
argumentList = candidate.callInfo.argumentList, argumentList = candidate.callInfo.argumentList,
safe = candidate.callInfo.isSafeCall,
) )
} else { } else {
resultExpression resultExpression
@@ -114,7 +113,6 @@ class FirCallResolver(
name, name,
explicitReceiver, explicitReceiver,
argumentList, argumentList,
qualifiedAccess.safe,
isPotentialQualifierPart = qualifiedAccess !is FirFunctionCall && isPotentialQualifierPart = qualifiedAccess !is FirFunctionCall &&
qualifiedAccess.explicitReceiver is FirResolvedQualifier && qualifiedAccess.explicitReceiver is FirResolvedQualifier &&
qualifiedResolver.isPotentialQualifierPartPosition(), qualifiedResolver.isPotentialQualifierPartPosition(),
@@ -151,7 +149,7 @@ class FirCallResolver(
fun <T : FirQualifiedAccess> resolveVariableAccessAndSelectCandidate(qualifiedAccess: T): FirStatement { fun <T : FirQualifiedAccess> resolveVariableAccessAndSelectCandidate(qualifiedAccess: T): FirStatement {
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
qualifiedResolver.initProcessingQualifiedAccess(qualifiedAccess, callee) qualifiedResolver.initProcessingQualifiedAccess(callee)
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val qualifiedAccess = qualifiedAccess.transformExplicitReceiver(transformer, ResolutionMode.ContextIndependent) val qualifiedAccess = qualifiedAccess.transformExplicitReceiver(transformer, ResolutionMode.ContextIndependent)
@@ -274,7 +272,6 @@ class FirCallResolver(
name, name,
explicitReceiver = null, explicitReceiver = null,
delegatedConstructorCall.argumentList, delegatedConstructorCall.argumentList,
isSafeCall = false,
isPotentialQualifierPart = false, isPotentialQualifierPart = false,
typeArguments = typeArguments, typeArguments = typeArguments,
session, session,
@@ -329,7 +326,6 @@ class FirCallResolver(
callableReferenceAccess.calleeReference.name, callableReferenceAccess.calleeReference.name,
callableReferenceAccess.explicitReceiver, callableReferenceAccess.explicitReceiver,
FirEmptyArgumentList, FirEmptyArgumentList,
false,
isPotentialQualifierPart = false, isPotentialQualifierPart = false,
emptyList(), emptyList(),
session, session,
@@ -40,8 +40,8 @@ class FirQualifiedNameResolver(components: BodyResolveComponents) : BodyResolveC
*/ */
fun isPotentialQualifierPartPosition() = qualifierStack.size > 1 fun isPotentialQualifierPartPosition() = qualifierStack.size > 1
fun initProcessingQualifiedAccess(qualifiedAccess: FirQualifiedAccess, callee: FirSimpleNamedReference) { fun initProcessingQualifiedAccess(callee: FirSimpleNamedReference) {
if (qualifiedAccess.safe || callee.name.isSpecial) { if (callee.name.isSpecial) {
qualifierStack.clear() qualifierStack.clear()
} else { } else {
qualifierStack.add(callee.name) qualifierStack.add(callee.name)
@@ -78,7 +78,6 @@ class FirQualifiedNameResolver(components: BodyResolveComponents) : BodyResolveC
this.source = source this.source = source
packageFqName = resolved.packageFqName packageFqName = resolved.packageFqName
relativeClassFqName = resolved.relativeClassFqName relativeClassFqName = resolved.relativeClassFqName
safe = false
symbol = resolved.classSymbol symbol = resolved.classSymbol
}.apply { }.apply {
resultType = typeForQualifier(this) resultType = typeForQualifier(this)
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.references.FirThisReference import org.jetbrains.kotlin.fir.references.FirThisReference
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
import org.jetbrains.kotlin.fir.resolve.calls.isSuperReferenceExpression
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -263,7 +262,6 @@ fun BodyResolveComponents.buildResolvedQualifierForClass(
source = sourceElement source = sourceElement
packageFqName = classId.packageFqName packageFqName = classId.packageFqName
relativeClassFqName = classId.relativeClassName relativeClassFqName = classId.relativeClassName
safe = false
typeArguments.addAll(typeArgumentsForQualifier) typeArguments.addAll(typeArgumentsForQualifier)
symbol = regularClass symbol = regularClass
}.apply { }.apply {
@@ -318,22 +316,6 @@ internal fun typeForQualifierByDeclaration(declaration: FirDeclaration, resultTy
} }
fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirResolvedTypeRef { fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirResolvedTypeRef {
val makeNullable: Boolean by lazy {
if (access is FirQualifiedAccess && access.safe) {
val explicitReceiver = access.explicitReceiver
?: throw AssertionError("Safe call without explicit receiver: ${access.render()}")
val receiverResultType = explicitReceiver.resultType
if (receiverResultType is FirResolvedTypeRef) {
receiverResultType.type.isNullable
} else if (receiverResultType !is FirComposedSuperTypeRef || !explicitReceiver.isSuperReferenceExpression()){
throw AssertionError("Receiver ${explicitReceiver.render()} type is unresolved: ${receiverResultType.render()}")
} else {
false
}
} else {
false
}
}
return when (val newCallee = access.calleeReference) { return when (val newCallee = access.calleeReference) {
is FirErrorNamedReference -> is FirErrorNamedReference ->
@@ -342,10 +324,10 @@ fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirReso
diagnostic = ConeStubDiagnostic(newCallee.diagnostic) diagnostic = ConeStubDiagnostic(newCallee.diagnostic)
} }
is FirNamedReferenceWithCandidate -> { is FirNamedReferenceWithCandidate -> {
typeFromSymbol(newCallee.candidateSymbol, makeNullable) typeFromSymbol(newCallee.candidateSymbol, false)
} }
is FirResolvedNamedReference -> { is FirResolvedNamedReference -> {
typeFromSymbol(newCallee.resolvedSymbol, makeNullable) typeFromSymbol(newCallee.resolvedSymbol, false)
} }
is FirThisReference -> { is FirThisReference -> {
val labelName = newCallee.labelName val labelName = newCallee.labelName
@@ -36,7 +36,6 @@ data class CallInfo(
val explicitReceiver: FirExpression?, val explicitReceiver: FirExpression?,
val argumentList: FirArgumentList, val argumentList: FirArgumentList,
val isSafeCall: Boolean,
val isPotentialQualifierPart: Boolean, val isPotentialQualifierPart: Boolean,
val typeArguments: List<FirTypeProjection>, val typeArguments: List<FirTypeProjection>,
@@ -678,7 +678,6 @@ private fun BodyResolveComponents.createExplicitReceiverForInvokeByCallable(
extensionReceiver = extensionReceiverExpression extensionReceiver = extensionReceiverExpression
// NB: this should fix problem in DFA (KT-36014) // NB: this should fix problem in DFA (KT-36014)
explicitReceiver = info.explicitReceiver explicitReceiver = info.explicitReceiver
safe = info.isSafeCall
} }
}.build().let(::transformQualifiedAccessUsingSmartcastInfo) }.build().let(::transformQualifiedAccessUsingSmartcastInfo)
} }
@@ -216,7 +216,6 @@ class ScopeTowerLevel(
val resolvedQualifier = buildResolvedQualifier { val resolvedQualifier = buildResolvedQualifier {
packageFqName = holderId.packageFqName packageFqName = holderId.packageFqName
relativeClassFqName = holderId.relativeClassName relativeClassFqName = holderId.relativeClassName
safe = false
this.symbol = symbol this.symbol = symbol
}.apply { }.apply {
resultType = bodyResolveComponents.typeForQualifier(this) resultType = bodyResolveComponents.typeForQualifier(this)
@@ -61,15 +61,7 @@ class FirCallCompletionResultsWriterTransformer(
val declaration = subCandidate.symbol.phasedFir val declaration = subCandidate.symbol.phasedFir
val typeArguments = computeTypeArguments(qualifiedAccess, subCandidate) val typeArguments = computeTypeArguments(qualifiedAccess, subCandidate)
val typeRef = if (declaration is FirTypedDeclaration) { val typeRef = if (declaration is FirTypedDeclaration) {
typeCalculator.tryCalculateReturnType(declaration).let { typeCalculator.tryCalculateReturnType(declaration)
if (qualifiedAccess.safe) {
val nullableType =
it.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE, session.inferenceContext)
it.withReplacedConeType(nullableType)
} else {
it
}
}
} else { } else {
buildErrorTypeRef { buildErrorTypeRef {
source = calleeReference.source source = calleeReference.source
@@ -153,7 +153,6 @@ class FirSyntheticCallGenerator(
name = name, name = name,
explicitReceiver = null, explicitReceiver = null,
argumentList = argumentList, argumentList = argumentList,
isSafeCall = false,
isPotentialQualifierPart = false, isPotentialQualifierPart = false,
typeArguments = emptyList(), typeArguments = emptyList(),
session = session, session = session,
@@ -222,7 +222,6 @@ private fun FirFunctionCall.toOperatorCall(): FirIntegerOperatorCall {
source, source,
typeRef, typeRef,
annotations.toMutableList(), annotations.toMutableList(),
safe,
typeArguments.toMutableList(), typeArguments.toMutableList(),
explicitReceiver, explicitReceiver,
dispatchReceiver, dispatchReceiver,
@@ -344,7 +344,6 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
val assignment = val assignment =
buildVariableAssignment { buildVariableAssignment {
source = operatorCall.source source = operatorCall.source
safe = false
rValue = resolvedOperatorCall rValue = resolvedOperatorCall
calleeReference = if (lhsIsVar) calleeReference = if (lhsIsVar)
lhsReference!! lhsReference!!
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirArgumentList
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.builder.FirCallBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirCallBuilder
import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder
import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessBuilder
@@ -28,7 +27,6 @@ class FirIntegerOperatorCall @FirImplementationDetail constructor(
source: FirSourceElement?, source: FirSourceElement?,
typeRef: FirTypeRef, typeRef: FirTypeRef,
annotations: MutableList<FirAnnotationCall>, annotations: MutableList<FirAnnotationCall>,
safe: Boolean,
typeArguments: MutableList<FirTypeProjection>, typeArguments: MutableList<FirTypeProjection>,
explicitReceiver: FirExpression?, explicitReceiver: FirExpression?,
dispatchReceiver: FirExpression, dispatchReceiver: FirExpression,
@@ -39,7 +37,6 @@ class FirIntegerOperatorCall @FirImplementationDetail constructor(
source, source,
typeRef, typeRef,
annotations, annotations,
safe,
typeArguments, typeArguments,
explicitReceiver, explicitReceiver,
dispatchReceiver, dispatchReceiver,
@@ -53,7 +50,6 @@ class FirIntegerOperatorCallBuilder : FirQualifiedAccessBuilder, FirCallBuilder,
override var source: FirSourceElement? = null override var source: FirSourceElement? = null
override var typeRef: FirTypeRef = buildImplicitTypeRef() override var typeRef: FirTypeRef = buildImplicitTypeRef()
override val annotations: MutableList<FirAnnotationCall> = mutableListOf() override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
override var safe: Boolean = false
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf() override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
override var explicitReceiver: FirExpression? = null override var explicitReceiver: FirExpression? = null
override var dispatchReceiver: FirExpression = FirNoReceiverExpression override var dispatchReceiver: FirExpression = FirNoReceiverExpression
@@ -67,7 +63,6 @@ class FirIntegerOperatorCallBuilder : FirQualifiedAccessBuilder, FirCallBuilder,
source, source,
typeRef, typeRef,
annotations, annotations,
safe,
typeArguments, typeArguments,
explicitReceiver, explicitReceiver,
dispatchReceiver, dispatchReceiver,
@@ -1006,11 +1006,7 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
} }
} }
if (hasSomeReceiver) { if (hasSomeReceiver) {
if (qualifiedAccess.safe) { print(".")
print("?.")
} else {
print(".")
}
} }
} }
@@ -30,7 +30,6 @@ internal class FirExpressionWithSmartcastImpl(
override val source: FirSourceElement? get() = originalExpression.source override val source: FirSourceElement? get() = originalExpression.source
override val annotations: List<FirAnnotationCall> get() = originalExpression.annotations override val annotations: List<FirAnnotationCall> get() = originalExpression.annotations
override val safe: Boolean get() = originalExpression.safe
override val typeArguments: List<FirTypeProjection> get() = originalExpression.typeArguments override val typeArguments: List<FirTypeProjection> get() = originalExpression.typeArguments
override val explicitReceiver: FirExpression? get() = originalExpression.explicitReceiver override val explicitReceiver: FirExpression? get() = originalExpression.explicitReceiver
override val dispatchReceiver: FirExpression get() = originalExpression.dispatchReceiver override val dispatchReceiver: FirExpression get() = originalExpression.dispatchReceiver