FIR: Make LHS of FirVariableAssignment a FirExpression
This way references can even be resolved for erroneous assignments (e.g. function call, if expression, ... on LHS) ^KT-54648 Fixed
This commit is contained in:
committed by
Space Team
parent
e9b8d6db80
commit
ace47c06a5
+2
-2
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.fir.FirModuleData
|
|||||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.*
|
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
@@ -306,7 +306,7 @@ internal object FirToKtConversionCreator {
|
|||||||
KtSymbol::class.createType(),
|
KtSymbol::class.createType(),
|
||||||
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
|
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
|
||||||
),
|
),
|
||||||
FirQualifiedAccess::class to HLFunctionCallConversion(
|
FirQualifiedAccessExpression::class to HLFunctionCallConversion(
|
||||||
"{0}.source!!.psi as KtExpression",
|
"{0}.source!!.psi as KtExpression",
|
||||||
KtExpression::class.createType(),
|
KtExpression::class.createType(),
|
||||||
importsToAdd = listOf(
|
importsToAdd = listOf(
|
||||||
|
|||||||
+5
-5
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||||
@@ -79,20 +79,20 @@ internal interface KtFirAnalysisSessionComponent {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirQualifiedAccess.createSubstitutorFromTypeArguments(): KtSubstitutor? {
|
fun FirQualifiedAccessExpression.createSubstitutorFromTypeArguments(): KtSubstitutor? {
|
||||||
return createConeSubstitutorFromTypeArguments()?.toKtSubstitutor()
|
return createConeSubstitutorFromTypeArguments()?.toKtSubstitutor()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirQualifiedAccess.createSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): KtSubstitutor {
|
fun FirQualifiedAccessExpression.createSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): KtSubstitutor {
|
||||||
return createConeSubstitutorFromTypeArguments(callableSymbol).toKtSubstitutor()
|
return createConeSubstitutorFromTypeArguments(callableSymbol).toKtSubstitutor()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirQualifiedAccess.createConeSubstitutorFromTypeArguments(): ConeSubstitutor? {
|
fun FirQualifiedAccessExpression.createConeSubstitutorFromTypeArguments(): ConeSubstitutor? {
|
||||||
val symbol = calleeReference.toResolvedCallableSymbol() ?: return null
|
val symbol = calleeReference.toResolvedCallableSymbol() ?: return null
|
||||||
return createConeSubstitutorFromTypeArguments(symbol)
|
return createConeSubstitutorFromTypeArguments(symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirQualifiedAccess.createConeSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): ConeSubstitutor {
|
fun FirQualifiedAccessExpression.createConeSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): ConeSubstitutor {
|
||||||
val typeArgumentMap = buildMap {
|
val typeArgumentMap = buildMap {
|
||||||
// Type arguments are ignored defensively if `callableSymbol` can't provide enough type parameters (and vice versa). For
|
// Type arguments are ignored defensively if `callableSymbol` can't provide enough type parameters (and vice versa). For
|
||||||
// example, when call candidates are collected, the candidate's `callableSymbol` might have fewer type parameters than the
|
// example, when call candidates are collected, the candidate's `callableSymbol` might have fewer type parameters than the
|
||||||
|
|||||||
+71
-44
@@ -124,9 +124,9 @@ internal class KtFirCallResolver(
|
|||||||
val containingBinaryExpressionForLhs = psi.getContainingBinaryExpressionForIncompleteLhs()
|
val containingBinaryExpressionForLhs = psi.getContainingBinaryExpressionForIncompleteLhs()
|
||||||
val containingUnaryExpressionForIncOrDec = psi.getContainingUnaryIncOrDecExpression()
|
val containingUnaryExpressionForIncOrDec = psi.getContainingUnaryIncOrDecExpression()
|
||||||
val psiToResolve = containingCallExpressionForCalleeExpression
|
val psiToResolve = containingCallExpressionForCalleeExpression
|
||||||
?: psi.getContainingDotQualifiedExpressionForSelectorExpression()
|
|
||||||
?: containingBinaryExpressionForLhs
|
?: containingBinaryExpressionForLhs
|
||||||
?: containingUnaryExpressionForIncOrDec
|
?: containingUnaryExpressionForIncOrDec
|
||||||
|
?: psi.getContainingDotQualifiedExpressionForSelectorExpression()
|
||||||
?: psi
|
?: psi
|
||||||
val fir = psiToResolve.getOrBuildFir(analysisSession.firResolveSession) ?: return emptyList()
|
val fir = psiToResolve.getOrBuildFir(analysisSession.firResolveSession) ?: return emptyList()
|
||||||
if (fir is FirDiagnosticHolder) {
|
if (fir is FirDiagnosticHolder) {
|
||||||
@@ -189,7 +189,7 @@ internal class KtFirCallResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> transformErrorReference(call: FirResolvable, calleeReference: T): KtCallInfo where T : FirNamedReference, T : FirDiagnosticHolder {
|
fun <T> transformErrorReference(call: FirElement, calleeReference: T): KtCallInfo where T : FirNamedReference, T : FirDiagnosticHolder {
|
||||||
val diagnostic = calleeReference.diagnostic
|
val diagnostic = calleeReference.diagnostic
|
||||||
val ktDiagnostic = calleeReference.createKtDiagnostic(psi)
|
val ktDiagnostic = calleeReference.createKtDiagnostic(psi)
|
||||||
|
|
||||||
@@ -199,16 +199,16 @@ internal class KtFirCallResolver(
|
|||||||
val candidateCalls = mutableListOf<KtCall>()
|
val candidateCalls = mutableListOf<KtCall>()
|
||||||
if (diagnostic is ConeDiagnosticWithCandidates) {
|
if (diagnostic is ConeDiagnosticWithCandidates) {
|
||||||
diagnostic.candidates.mapNotNullTo(candidateCalls) {
|
diagnostic.candidates.mapNotNullTo(candidateCalls) {
|
||||||
createKtCall(psi, call, it, resolveFragmentOfCall)
|
createKtCall(psi, call, calleeReference, it, resolveFragmentOfCall)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
candidateCalls.addIfNotNull(createKtCall(psi, call, null, resolveFragmentOfCall))
|
candidateCalls.addIfNotNull(createKtCall(psi, call, calleeReference, null, resolveFragmentOfCall))
|
||||||
}
|
}
|
||||||
return KtErrorCallInfo(candidateCalls, ktDiagnostic, token)
|
return KtErrorCallInfo(candidateCalls, ktDiagnostic, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FirResolvable -> {
|
is FirResolvable, is FirVariableAssignment -> {
|
||||||
when (val calleeReference = calleeReference) {
|
when (val calleeReference = calleeReference) {
|
||||||
is FirResolvedErrorReference -> transformErrorReference(this, calleeReference)
|
is FirResolvedErrorReference -> transformErrorReference(this, calleeReference)
|
||||||
is FirResolvedNamedReference -> when (calleeReference.resolvedSymbol) {
|
is FirResolvedNamedReference -> when (calleeReference.resolvedSymbol) {
|
||||||
@@ -216,7 +216,7 @@ internal class KtFirCallResolver(
|
|||||||
// expression positions (e.g. `T` in `println(T)`) are parsed as `KtSimpleNameExpression` and built into
|
// expression positions (e.g. `T` in `println(T)`) are parsed as `KtSimpleNameExpression` and built into
|
||||||
// `FirPropertyAccessExpression` (which is `FirResolvable`).
|
// `FirPropertyAccessExpression` (which is `FirResolvable`).
|
||||||
is FirCallableSymbol<*> -> {
|
is FirCallableSymbol<*> -> {
|
||||||
val call = createKtCall(psi, this, null, resolveFragmentOfCall)
|
val call = createKtCall(psi, this, calleeReference, null, resolveFragmentOfCall)
|
||||||
?: errorWithFirSpecificEntries(
|
?: errorWithFirSpecificEntries(
|
||||||
"expect `createKtCall` to succeed for resolvable case with callable symbol",
|
"expect `createKtCall` to succeed for resolvable case with callable symbol",
|
||||||
fir = this,
|
fir = this,
|
||||||
@@ -307,7 +307,9 @@ internal class KtFirCallResolver(
|
|||||||
if (this !is KtExpression) return null
|
if (this !is KtExpression) return null
|
||||||
val lhs = deparenthesize(this)
|
val lhs = deparenthesize(this)
|
||||||
val binaryExpression = parentOfType<KtBinaryExpression>() ?: return null
|
val binaryExpression = parentOfType<KtBinaryExpression>() ?: return null
|
||||||
if (deparenthesize(binaryExpression.left) != lhs || binaryExpression.operationToken !in KtTokens.ALL_ASSIGNMENTS) return null
|
if (binaryExpression.operationToken !in KtTokens.ALL_ASSIGNMENTS) return null
|
||||||
|
val leftOfBinary = deparenthesize(binaryExpression.left)
|
||||||
|
if (leftOfBinary != lhs && !(leftOfBinary is KtDotQualifiedExpression && leftOfBinary.selectorExpression == lhs)) return null
|
||||||
val firBinaryExpression = binaryExpression.getOrBuildFir(analysisSession.firResolveSession)
|
val firBinaryExpression = binaryExpression.getOrBuildFir(analysisSession.firResolveSession)
|
||||||
if (firBinaryExpression is FirFunctionCall) {
|
if (firBinaryExpression is FirFunctionCall) {
|
||||||
if (firBinaryExpression.origin == FirFunctionCallOrigin.Operator &&
|
if (firBinaryExpression.origin == FirFunctionCallOrigin.Operator &&
|
||||||
@@ -349,9 +351,19 @@ internal class KtFirCallResolver(
|
|||||||
fir: FirResolvable,
|
fir: FirResolvable,
|
||||||
candidate: AbstractCandidate?,
|
candidate: AbstractCandidate?,
|
||||||
resolveFragmentOfCall: Boolean
|
resolveFragmentOfCall: Boolean
|
||||||
|
): KtCall? {
|
||||||
|
return createKtCall(psi, fir, fir.calleeReference, candidate, resolveFragmentOfCall)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createKtCall(
|
||||||
|
psi: KtElement,
|
||||||
|
fir: FirElement,
|
||||||
|
calleeReference: FirReference,
|
||||||
|
candidate: AbstractCandidate?,
|
||||||
|
resolveFragmentOfCall: Boolean
|
||||||
): KtCall? {
|
): KtCall? {
|
||||||
val targetSymbol = candidate?.symbol
|
val targetSymbol = candidate?.symbol
|
||||||
?: fir.calleeReference.toResolvedBaseSymbol()
|
?: calleeReference.toResolvedBaseSymbol()
|
||||||
?: return null
|
?: return null
|
||||||
if (targetSymbol !is FirCallableSymbol<*>) return null
|
if (targetSymbol !is FirCallableSymbol<*>) return null
|
||||||
if (targetSymbol is FirErrorFunctionSymbol || targetSymbol is FirErrorPropertySymbol) return null
|
if (targetSymbol is FirErrorFunctionSymbol || targetSymbol is FirErrorPropertySymbol) return null
|
||||||
@@ -365,8 +377,11 @@ internal class KtFirCallResolver(
|
|||||||
// TODO: Ideally, we should get the substitutor from the candidate. But it seems there is no way to get the substitutor from the
|
// TODO: Ideally, we should get the substitutor from the candidate. But it seems there is no way to get the substitutor from the
|
||||||
// candidate, `Candidate.substitutor` is not complete. maybe we can carry over the final substitutor if it's available from
|
// candidate, `Candidate.substitutor` is not complete. maybe we can carry over the final substitutor if it's available from
|
||||||
// body resolve phase?
|
// body resolve phase?
|
||||||
val substitutor =
|
val substitutor = when (fir) {
|
||||||
(fir as? FirQualifiedAccess)?.createSubstitutorFromTypeArguments(targetSymbol) ?: KtSubstitutor.Empty(token)
|
is FirQualifiedAccessExpression -> fir.createSubstitutorFromTypeArguments(targetSymbol)
|
||||||
|
is FirVariableAssignment -> fir.unwrapLValue()?.createSubstitutorFromTypeArguments(targetSymbol)
|
||||||
|
else -> null
|
||||||
|
} ?: KtSubstitutor.Empty(token)
|
||||||
|
|
||||||
fun createKtPartiallyAppliedSymbolForImplicitInvoke(
|
fun createKtPartiallyAppliedSymbolForImplicitInvoke(
|
||||||
dispatchReceiver: FirExpression,
|
dispatchReceiver: FirExpression,
|
||||||
@@ -393,7 +408,8 @@ internal class KtFirCallResolver(
|
|||||||
val dispatchReceiverValue: KtReceiverValue?
|
val dispatchReceiverValue: KtReceiverValue?
|
||||||
val extensionReceiverValue: KtReceiverValue?
|
val extensionReceiverValue: KtReceiverValue?
|
||||||
if (explicitReceiverKind == ExplicitReceiverKind.DISPATCH_RECEIVER) {
|
if (explicitReceiverKind == ExplicitReceiverKind.DISPATCH_RECEIVER) {
|
||||||
dispatchReceiverValue = KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.typeRef.coneType.asKtType(), false, token)
|
dispatchReceiverValue =
|
||||||
|
KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.typeRef.coneType.asKtType(), false, token)
|
||||||
if (firstArgIsExtensionReceiver) {
|
if (firstArgIsExtensionReceiver) {
|
||||||
extensionReceiverValue = (fir as FirFunctionCall).arguments.first().toKtReceiverValue()
|
extensionReceiverValue = (fir as FirFunctionCall).arguments.first().toKtReceiverValue()
|
||||||
} else {
|
} else {
|
||||||
@@ -401,7 +417,8 @@ internal class KtFirCallResolver(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dispatchReceiverValue = dispatchReceiver.toKtReceiverValue()
|
dispatchReceiverValue = dispatchReceiver.toKtReceiverValue()
|
||||||
extensionReceiverValue = KtExplicitReceiverValue(explicitReceiverPsi, extensionReceiver.typeRef.coneType.asKtType(), false, token)
|
extensionReceiverValue =
|
||||||
|
KtExplicitReceiverValue(explicitReceiverPsi, extensionReceiver.typeRef.coneType.asKtType(), false, token)
|
||||||
}
|
}
|
||||||
return KtPartiallyAppliedSymbol(
|
return KtPartiallyAppliedSymbol(
|
||||||
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
|
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
|
||||||
@@ -412,7 +429,7 @@ internal class KtFirCallResolver(
|
|||||||
|
|
||||||
val partiallyAppliedSymbol = if (candidate != null) {
|
val partiallyAppliedSymbol = if (candidate != null) {
|
||||||
if (fir is FirImplicitInvokeCall ||
|
if (fir is FirImplicitInvokeCall ||
|
||||||
(fir.calleeOrCandidateName != OperatorNameConventions.INVOKE && targetSymbol.isInvokeFunction())
|
(calleeReference.calleeOrCandidateName != OperatorNameConventions.INVOKE && targetSymbol.isInvokeFunction())
|
||||||
) {
|
) {
|
||||||
// Implicit invoke (e.g., `x()`) will have a different callee symbol (e.g., `x`) than the candidate (e.g., `invoke`).
|
// Implicit invoke (e.g., `x()`) will have a different callee symbol (e.g., `x`) than the candidate (e.g., `invoke`).
|
||||||
createKtPartiallyAppliedSymbolForImplicitInvoke(
|
createKtPartiallyAppliedSymbolForImplicitInvoke(
|
||||||
@@ -427,21 +444,25 @@ internal class KtFirCallResolver(
|
|||||||
candidate.chosenExtensionReceiverValue?.receiverExpression?.toKtReceiverValue(),
|
candidate.chosenExtensionReceiverValue?.receiverExpression?.toKtReceiverValue(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (fir is FirQualifiedAccess) {
|
} else if (fir is FirImplicitInvokeCall) {
|
||||||
if (fir is FirImplicitInvokeCall) {
|
val explicitReceiverKind = if (fir.explicitReceiver == fir.dispatchReceiver) {
|
||||||
val explicitReceiverKind = if (fir.explicitReceiver == fir.dispatchReceiver) {
|
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
ExplicitReceiverKind.DISPATCH_RECEIVER
|
|
||||||
} else {
|
|
||||||
ExplicitReceiverKind.EXTENSION_RECEIVER
|
|
||||||
}
|
|
||||||
createKtPartiallyAppliedSymbolForImplicitInvoke(fir.dispatchReceiver, fir.extensionReceiver, explicitReceiverKind)
|
|
||||||
} else {
|
} else {
|
||||||
KtPartiallyAppliedSymbol(
|
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
|
|
||||||
fir.dispatchReceiver.toKtReceiverValue(),
|
|
||||||
fir.extensionReceiver.toKtReceiverValue()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
createKtPartiallyAppliedSymbolForImplicitInvoke(fir.dispatchReceiver, fir.extensionReceiver, explicitReceiverKind)
|
||||||
|
} else if (fir is FirQualifiedAccessExpression) {
|
||||||
|
KtPartiallyAppliedSymbol(
|
||||||
|
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
|
||||||
|
fir.dispatchReceiver.toKtReceiverValue(),
|
||||||
|
fir.extensionReceiver.toKtReceiverValue()
|
||||||
|
)
|
||||||
|
} else if (fir is FirVariableAssignment) {
|
||||||
|
KtPartiallyAppliedSymbol(
|
||||||
|
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
|
||||||
|
fir.dispatchReceiver.toKtReceiverValue(),
|
||||||
|
fir.extensionReceiver.toKtReceiverValue()
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
KtPartiallyAppliedSymbol(unsubstitutedKtSignature, _dispatchReceiver = null, _extensionReceiver = null)
|
KtPartiallyAppliedSymbol(unsubstitutedKtSignature, _dispatchReceiver = null, _extensionReceiver = null)
|
||||||
}
|
}
|
||||||
@@ -470,7 +491,7 @@ internal class KtFirCallResolver(
|
|||||||
@Suppress("UNCHECKED_CAST") // safe because of the above check on targetKtSymbol
|
@Suppress("UNCHECKED_CAST") // safe because of the above check on targetKtSymbol
|
||||||
KtSimpleVariableAccessCall(
|
KtSimpleVariableAccessCall(
|
||||||
partiallyAppliedSymbol as KtPartiallyAppliedVariableSymbol<KtVariableLikeSymbol>,
|
partiallyAppliedSymbol as KtPartiallyAppliedVariableSymbol<KtVariableLikeSymbol>,
|
||||||
fir.toTypeArgumentsMapping(partiallyAppliedSymbol),
|
fir.unwrapLValue()?.toTypeArgumentsMapping(partiallyAppliedSymbol) ?: emptyMap(),
|
||||||
KtSimpleVariableAccess.Write(rhs)
|
KtSimpleVariableAccess.Write(rhs)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -519,12 +540,19 @@ internal class KtFirCallResolver(
|
|||||||
isImplicitInvoke
|
isImplicitInvoke
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is FirSmartCastExpression -> (fir.originalExpression as? FirResolvable)?.let { createKtCall(psi, it, candidate, resolveFragmentOfCall) }
|
is FirSmartCastExpression -> (fir.originalExpression as? FirResolvable)?.let {
|
||||||
|
createKtCall(
|
||||||
|
psi,
|
||||||
|
it,
|
||||||
|
candidate,
|
||||||
|
resolveFragmentOfCall
|
||||||
|
)
|
||||||
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleCompoundAccessCall(psi: KtElement, fir: FirResolvable, resolveFragmentOfCall: Boolean): KtCall? {
|
private fun handleCompoundAccessCall(psi: KtElement, fir: FirElement, resolveFragmentOfCall: Boolean): KtCall? {
|
||||||
if (psi is KtBinaryExpression && psi.operationToken in KtTokens.AUGMENTED_ASSIGNMENTS) {
|
if (psi is KtBinaryExpression && psi.operationToken in KtTokens.AUGMENTED_ASSIGNMENTS) {
|
||||||
val rightOperandPsi = deparenthesize(psi.right) ?: return null
|
val rightOperandPsi = deparenthesize(psi.right) ?: return null
|
||||||
val leftOperandPsi = deparenthesize(psi.left) ?: return null
|
val leftOperandPsi = deparenthesize(psi.left) ?: return null
|
||||||
@@ -566,13 +594,13 @@ internal class KtFirCallResolver(
|
|||||||
return if (resolveFragmentOfCall) {
|
return if (resolveFragmentOfCall) {
|
||||||
KtSimpleVariableAccessCall(
|
KtSimpleVariableAccessCall(
|
||||||
variablePartiallyAppliedSymbol,
|
variablePartiallyAppliedSymbol,
|
||||||
fir.toTypeArgumentsMapping(variablePartiallyAppliedSymbol),
|
fir.unwrapLValue()?.toTypeArgumentsMapping(variablePartiallyAppliedSymbol) ?: emptyMap(),
|
||||||
KtSimpleVariableAccess.Read
|
KtSimpleVariableAccess.Read
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
KtCompoundVariableAccessCall(
|
KtCompoundVariableAccessCall(
|
||||||
variablePartiallyAppliedSymbol,
|
variablePartiallyAppliedSymbol,
|
||||||
fir.toTypeArgumentsMapping(variablePartiallyAppliedSymbol),
|
fir.unwrapLValue()?.toTypeArgumentsMapping(variablePartiallyAppliedSymbol) ?: emptyMap(),
|
||||||
KtCompoundAccess.CompoundAssign(operationPartiallyAppliedSymbol, compoundAssignKind, rightOperandPsi),
|
KtCompoundAccess.CompoundAssign(operationPartiallyAppliedSymbol, compoundAssignKind, rightOperandPsi),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -620,13 +648,13 @@ internal class KtFirCallResolver(
|
|||||||
return if (resolveFragmentOfCall) {
|
return if (resolveFragmentOfCall) {
|
||||||
KtSimpleVariableAccessCall(
|
KtSimpleVariableAccessCall(
|
||||||
variablePartiallyAppliedSymbol,
|
variablePartiallyAppliedSymbol,
|
||||||
fir.toTypeArgumentsMapping(variablePartiallyAppliedSymbol),
|
fir.unwrapLValue()?.toTypeArgumentsMapping(variablePartiallyAppliedSymbol) ?: emptyMap(),
|
||||||
KtSimpleVariableAccess.Read
|
KtSimpleVariableAccess.Read
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
KtCompoundVariableAccessCall(
|
KtCompoundVariableAccessCall(
|
||||||
variablePartiallyAppliedSymbol,
|
variablePartiallyAppliedSymbol,
|
||||||
fir.toTypeArgumentsMapping(variablePartiallyAppliedSymbol),
|
fir.unwrapLValue()?.toTypeArgumentsMapping(variablePartiallyAppliedSymbol) ?: emptyMap(),
|
||||||
KtCompoundAccess.IncOrDecOperation(operationPartiallyAppliedSymbol, incOrDecOperationKind, incDecPrecedence),
|
KtCompoundAccess.IncOrDecOperation(operationPartiallyAppliedSymbol, incOrDecOperationKind, incDecPrecedence),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -707,10 +735,7 @@ internal class KtFirCallResolver(
|
|||||||
|
|
||||||
@OptIn(SymbolInternals::class)
|
@OptIn(SymbolInternals::class)
|
||||||
private fun getInitializerOfReferencedLocalVariable(variableReference: FirExpression): FirFunctionCall? {
|
private fun getInitializerOfReferencedLocalVariable(variableReference: FirExpression): FirFunctionCall? {
|
||||||
val qualifiedAccess = variableReference as? FirQualifiedAccess
|
return variableReference.toReference()?.toResolvedVariableSymbol()?.fir?.initializer as? FirFunctionCall
|
||||||
val resolvedNamedReference = qualifiedAccess?.calleeReference as? FirResolvedNamedReference
|
|
||||||
val unaryResult = resolvedNamedReference?.resolvedSymbol as? FirVariableSymbol<*>
|
|
||||||
return unaryResult?.fir?.initializer as? FirFunctionCall
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getOperationPartiallyAppliedSymbolsForCompoundVariableAccess(
|
private fun getOperationPartiallyAppliedSymbolsForCompoundVariableAccess(
|
||||||
@@ -718,14 +743,14 @@ internal class KtFirCallResolver(
|
|||||||
leftOperandPsi: KtExpression
|
leftOperandPsi: KtExpression
|
||||||
): KtPartiallyAppliedFunctionSymbol<KtFunctionSymbol>? {
|
): KtPartiallyAppliedFunctionSymbol<KtFunctionSymbol>? {
|
||||||
// The new value is a call to the appropriate operator function.
|
// The new value is a call to the appropriate operator function.
|
||||||
val operationCall = fir.rValue as? FirFunctionCall ?: return null
|
val operationCall = fir.rValue as? FirFunctionCall ?: getInitializerOfReferencedLocalVariable(fir.rValue) ?: return null
|
||||||
return operationCall.toPartiallyAppliedSymbol(leftOperandPsi)
|
return operationCall.toPartiallyAppliedSymbol(leftOperandPsi)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirVariableAssignment.toPartiallyAppliedSymbol(): KtPartiallyAppliedVariableSymbol<KtVariableLikeSymbol>? {
|
private fun FirVariableAssignment.toPartiallyAppliedSymbol(): KtPartiallyAppliedVariableSymbol<KtVariableLikeSymbol>? {
|
||||||
val variableRef = calleeReference as? FirResolvedNamedReference ?: return null
|
val variableRef = calleeReference as? FirResolvedNamedReference ?: return null
|
||||||
val variableSymbol = variableRef.resolvedSymbol as? FirVariableSymbol<*> ?: return null
|
val variableSymbol = variableRef.resolvedSymbol as? FirVariableSymbol<*> ?: return null
|
||||||
val substitutor = createConeSubstitutorFromTypeArguments() ?: return null
|
val substitutor = unwrapLValue()?.createConeSubstitutorFromTypeArguments() ?: return null
|
||||||
val ktSignature = variableSymbol.toKtSignature()
|
val ktSignature = variableSymbol.toKtSignature()
|
||||||
return KtPartiallyAppliedSymbol(
|
return KtPartiallyAppliedSymbol(
|
||||||
with(analysisSession) { ktSignature.substitute(substitutor.toKtSubstitutor()) },
|
with(analysisSession) { ktSignature.substitute(substitutor.toKtSubstitutor()) },
|
||||||
@@ -801,7 +826,7 @@ internal class KtFirCallResolver(
|
|||||||
private fun FirVariableSymbol<*>.toKtSignature(): KtVariableLikeSignature<KtVariableLikeSymbol> =
|
private fun FirVariableSymbol<*>.toKtSignature(): KtVariableLikeSignature<KtVariableLikeSymbol> =
|
||||||
firSymbolBuilder.variableLikeBuilder.buildVariableLikeSignature(this)
|
firSymbolBuilder.variableLikeBuilder.buildVariableLikeSignature(this)
|
||||||
|
|
||||||
private fun FirQualifiedAccess.toTypeArgumentsMapping(
|
private fun FirQualifiedAccessExpression.toTypeArgumentsMapping(
|
||||||
partiallyAppliedSymbol: KtPartiallyAppliedSymbol<*, *>
|
partiallyAppliedSymbol: KtPartiallyAppliedSymbol<*, *>
|
||||||
): Map<KtTypeParameterSymbol, KtType> {
|
): Map<KtTypeParameterSymbol, KtType> {
|
||||||
return toTypeArgumentsMapping(typeArguments, partiallyAppliedSymbol)
|
return toTypeArgumentsMapping(typeArguments, partiallyAppliedSymbol)
|
||||||
@@ -1048,9 +1073,11 @@ internal class KtFirCallResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val FirResolvable.calleeOrCandidateName: Name?
|
private val FirResolvable.calleeOrCandidateName: Name?
|
||||||
|
get() = this.calleeReference.calleeOrCandidateName
|
||||||
|
|
||||||
|
private val FirReference.calleeOrCandidateName: Name?
|
||||||
get() {
|
get() {
|
||||||
val calleeReference = calleeReference
|
if (this !is FirNamedReference) return null
|
||||||
if (calleeReference !is FirNamedReference) return null
|
|
||||||
|
|
||||||
// In most cases, we can get the callee name from the callee's candidate symbols. However, there is at least one case where we
|
// In most cases, we can get the callee name from the callee's candidate symbols. However, there is at least one case where we
|
||||||
// cannot do so:
|
// cannot do so:
|
||||||
@@ -1064,13 +1091,13 @@ internal class KtFirCallResolver(
|
|||||||
// ```
|
// ```
|
||||||
// The candidates for the call will both be `invoke`. We can keep it simple by getting the name from the callee reference's PSI
|
// The candidates for the call will both be `invoke`. We can keep it simple by getting the name from the callee reference's PSI
|
||||||
// element (`x` in the above example) if possible.
|
// element (`x` in the above example) if possible.
|
||||||
return when (val psi = calleeReference.psi) {
|
return when (val psi = psi) {
|
||||||
is KtNameReferenceExpression -> psi.getReferencedNameAsName()
|
is KtNameReferenceExpression -> psi.getReferencedNameAsName()
|
||||||
else -> {
|
else -> {
|
||||||
// This could be KtArrayAccessExpression or KtOperationReferenceExpression.
|
// This could be KtArrayAccessExpression or KtOperationReferenceExpression.
|
||||||
// Note: All candidate symbols should have the same name. We go by the symbol because `calleeReference.name` will include
|
// Note: All candidate symbols should have the same name. We go by the symbol because `calleeReference.name` will include
|
||||||
// the applicability if not successful.
|
// the applicability if not successful.
|
||||||
calleeReference.getCandidateSymbols().firstOrNull()?.safeAs<FirCallableSymbol<*>>()?.name
|
getCandidateSymbols().firstOrNull()?.safeAs<FirCallableSymbol<*>>()?.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.resolve.constructFunctionalType
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
@@ -58,7 +59,9 @@ internal class KtFirExpressionTypeProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FirVariableAssignment -> {
|
is FirVariableAssignment -> {
|
||||||
if (expression is KtUnaryExpression && expression.operationToken in KtTokens.INCREMENT_AND_DECREMENT) {
|
if (fir.lValue.source?.psi == expression) {
|
||||||
|
fir.lValue.typeRef.coneType.asKtType()
|
||||||
|
} else if (expression is KtUnaryExpression && expression.operationToken in KtTokens.INCREMENT_AND_DECREMENT) {
|
||||||
fir.rValue.typeRef.coneType.asKtType()
|
fir.rValue.typeRef.coneType.asKtType()
|
||||||
} else {
|
} else {
|
||||||
analysisSession.builtinTypes.UNIT
|
analysisSession.builtinTypes.UNIT
|
||||||
|
|||||||
+3
-3
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
@@ -71,7 +71,7 @@ private fun convertArgument(argument: Any?, firSymbolBuilder: KtSymbolByFirBuild
|
|||||||
is FirCallableDeclaration -> convertArgument(argument, firSymbolBuilder)
|
is FirCallableDeclaration -> convertArgument(argument, firSymbolBuilder)
|
||||||
is FirMemberDeclaration -> convertArgument(argument, firSymbolBuilder)
|
is FirMemberDeclaration -> convertArgument(argument, firSymbolBuilder)
|
||||||
is FirDeclaration -> convertArgument(argument, firSymbolBuilder)
|
is FirDeclaration -> convertArgument(argument, firSymbolBuilder)
|
||||||
is FirQualifiedAccess -> convertArgument(argument, firSymbolBuilder)
|
is FirQualifiedAccessExpression -> convertArgument(argument, firSymbolBuilder)
|
||||||
is FirExpression -> convertArgument(argument, firSymbolBuilder)
|
is FirExpression -> convertArgument(argument, firSymbolBuilder)
|
||||||
is ConeKotlinType -> convertArgument(argument, firSymbolBuilder)
|
is ConeKotlinType -> convertArgument(argument, firSymbolBuilder)
|
||||||
is FirTypeRef -> convertArgument(argument, firSymbolBuilder)
|
is FirTypeRef -> convertArgument(argument, firSymbolBuilder)
|
||||||
@@ -163,7 +163,7 @@ private fun convertArgument(argument: FirDeclaration, firSymbolBuilder: KtSymbol
|
|||||||
return firSymbolBuilder.buildSymbol(argument)
|
return firSymbolBuilder.buildSymbol(argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertArgument(argument: FirQualifiedAccess, firSymbolBuilder: KtSymbolByFirBuilder): Any? {
|
private fun convertArgument(argument: FirQualifiedAccessExpression, firSymbolBuilder: KtSymbolByFirBuilder): Any? {
|
||||||
return argument.source!!.psi as KtExpression
|
return argument.source!!.psi as KtExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -309,7 +309,7 @@ internal object FirReferenceResolveHelper {
|
|||||||
symbolBuilder: KtSymbolByFirBuilder,
|
symbolBuilder: KtSymbolByFirBuilder,
|
||||||
): Collection<KtSymbol> {
|
): Collection<KtSymbol> {
|
||||||
if (expression is KtNameReferenceExpression) {
|
if (expression is KtNameReferenceExpression) {
|
||||||
return fir.calleeReference.toTargetSymbol(session, symbolBuilder)
|
return fir.calleeReference?.toTargetSymbol(session, symbolBuilder) ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val assignmentRValue = fir.rValue
|
val assignmentRValue = fir.rValue
|
||||||
|
|||||||
+8
-2
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.RawFirNonLoc
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.declarationCanBeLazilyResolved
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.declarationCanBeLazilyResolved
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
@@ -226,7 +227,12 @@ internal class NonReanalyzableDeclarationStructureElement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class DanglingTopLevelModifierListStructureElement(firFile: FirFile, val fir: FirDeclaration, moduleComponents: LLFirModuleResolveComponents, override val psi: KtAnnotated) :
|
internal class DanglingTopLevelModifierListStructureElement(
|
||||||
|
firFile: FirFile,
|
||||||
|
val fir: FirDeclaration,
|
||||||
|
moduleComponents: LLFirModuleResolveComponents,
|
||||||
|
override val psi: KtAnnotated
|
||||||
|
) :
|
||||||
FileStructureElement(firFile, moduleComponents) {
|
FileStructureElement(firFile, moduleComponents) {
|
||||||
override val mappings = KtToFirMapping(fir, FirElementsRecorder())
|
override val mappings = KtToFirMapping(fir, FirElementsRecorder())
|
||||||
|
|
||||||
@@ -252,4 +258,4 @@ internal class RootStructureElement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -63,7 +63,8 @@ internal open class FirElementsRecorder : FirVisitor<Unit, MutableMap<KtElement,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: MutableMap<KtElement, FirElement>) {
|
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: MutableMap<KtElement, FirElement>) {
|
||||||
cacheElement(variableAssignment.lValue, data) // FirReference is not cached by default
|
// For the LHS of the assignment, record the assignment itself
|
||||||
|
(variableAssignment.lValue.source?.psi as? KtElement)?.let { cache(it, variableAssignment, data) }
|
||||||
visitElement(variableAssignment, data)
|
visitElement(variableAssignment, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
|||||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
|
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.calleeReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableCandidate
|
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableCandidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
||||||
@@ -120,7 +120,7 @@ class AllCandidatesResolver(private val firSession: FirSession) {
|
|||||||
* resulting candidate is *not* marked as inapplicable and needs to be post-processed.
|
* resulting candidate is *not* marked as inapplicable and needs to be post-processed.
|
||||||
*/
|
*/
|
||||||
private fun OverloadCandidate.preserveCalleeInapplicability() {
|
private fun OverloadCandidate.preserveCalleeInapplicability() {
|
||||||
val callSite = candidate.callInfo.callSite as? FirQualifiedAccess ?: return
|
val callSite = candidate.callInfo.callSite
|
||||||
val calleeReference = callSite.calleeReference as? FirDiagnosticHolder ?: return
|
val calleeReference = callSite.calleeReference as? FirDiagnosticHolder ?: return
|
||||||
val diagnostic = calleeReference.diagnostic as? ConeInapplicableCandidateError ?: return
|
val diagnostic = calleeReference.diagnostic as? ConeInapplicableCandidateError ?: return
|
||||||
if (diagnostic.applicability != CandidateApplicability.INAPPLICABLE) return
|
if (diagnostic.applicability != CandidateApplicability.INAPPLICABLE) return
|
||||||
|
|||||||
-1
@@ -31,7 +31,6 @@ fun main(args: Array<String>) {
|
|||||||
val expressionPackage = "$basePackage.checkers.expression"
|
val expressionPackage = "$basePackage.checkers.expression"
|
||||||
generateCheckersComponents(generationPath, expressionPackage, "FirExpressionChecker") {
|
generateCheckersComponents(generationPath, expressionPackage, "FirExpressionChecker") {
|
||||||
alias<FirStatement>("BasicExpressionChecker")
|
alias<FirStatement>("BasicExpressionChecker")
|
||||||
alias<FirQualifiedAccess>("QualifiedAccessChecker")
|
|
||||||
alias<FirQualifiedAccessExpression>("QualifiedAccessExpressionChecker")
|
alias<FirQualifiedAccessExpression>("QualifiedAccessExpressionChecker")
|
||||||
alias<FirCall>("CallChecker")
|
alias<FirCall>("CallChecker")
|
||||||
alias<FirFunctionCall>("FunctionCallChecker")
|
alias<FirFunctionCall>("FunctionCallChecker")
|
||||||
|
|||||||
+5
-5
@@ -64,7 +64,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val BREAK_OR_CONTINUE_OUTSIDE_A_LOOP by error<PsiElement>()
|
val BREAK_OR_CONTINUE_OUTSIDE_A_LOOP by error<PsiElement>()
|
||||||
val NOT_A_LOOP_LABEL by error<PsiElement>()
|
val NOT_A_LOOP_LABEL by error<PsiElement>()
|
||||||
val BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY by error<KtExpressionWithLabel>()
|
val BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY by error<KtExpressionWithLabel>()
|
||||||
val VARIABLE_EXPECTED by error<PsiElement>(PositioningStrategy.ASSIGNMENT_LHS)
|
val VARIABLE_EXPECTED by error<PsiElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED)
|
||||||
val DELEGATION_IN_INTERFACE by error<PsiElement>()
|
val DELEGATION_IN_INTERFACE by error<PsiElement>()
|
||||||
val DELEGATION_NOT_TO_INTERFACE by error<PsiElement>()
|
val DELEGATION_NOT_TO_INTERFACE by error<PsiElement>()
|
||||||
val NESTED_CLASS_NOT_ALLOWED by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
|
val NESTED_CLASS_NOT_ALLOWED by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
|
||||||
@@ -91,7 +91,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by error<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by error<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||||
parameter<KtKeywordToken>("valOrVar")
|
parameter<KtKeywordToken>("valOrVar")
|
||||||
}
|
}
|
||||||
val INVISIBLE_SETTER by error<PsiElement>(PositioningStrategy.ASSIGNMENT_LHS) {
|
val INVISIBLE_SETTER by error<PsiElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED) {
|
||||||
parameter<FirPropertySymbol>("property")
|
parameter<FirPropertySymbol>("property")
|
||||||
parameter<Visibility>("visibility")
|
parameter<Visibility>("visibility")
|
||||||
parameter<CallableId>("callableId")
|
parameter<CallableId>("callableId")
|
||||||
@@ -1135,10 +1135,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val UNINITIALIZED_ENUM_COMPANION by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
|
val UNINITIALIZED_ENUM_COMPANION by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
|
||||||
parameter<FirRegularClassSymbol>("enumClass")
|
parameter<FirRegularClassSymbol>("enumClass")
|
||||||
}
|
}
|
||||||
val VAL_REASSIGNMENT by error<KtExpression> {
|
val VAL_REASSIGNMENT by error<KtExpression>(PositioningStrategy.SELECTOR_BY_QUALIFIED) {
|
||||||
parameter<FirVariableSymbol<*>>("variable")
|
parameter<FirVariableSymbol<*>>("variable")
|
||||||
}
|
}
|
||||||
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by deprecationError<KtExpression>(LanguageFeature.RestrictionOfValReassignmentViaBackingField) {
|
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by deprecationError<KtExpression>(LanguageFeature.RestrictionOfValReassignmentViaBackingField, PositioningStrategy.SELECTOR_BY_QUALIFIED) {
|
||||||
parameter<FirBackingFieldSymbol>("property")
|
parameter<FirBackingFieldSymbol>("property")
|
||||||
}
|
}
|
||||||
val CAPTURED_VAL_INITIALIZATION by error<KtExpression> {
|
val CAPTURED_VAL_INITIALIZATION by error<KtExpression> {
|
||||||
@@ -1147,7 +1147,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val CAPTURED_MEMBER_VAL_INITIALIZATION by error<KtExpression> {
|
val CAPTURED_MEMBER_VAL_INITIALIZATION by error<KtExpression> {
|
||||||
parameter<FirPropertySymbol>("property")
|
parameter<FirPropertySymbol>("property")
|
||||||
}
|
}
|
||||||
val SETTER_PROJECTED_OUT by error<KtBinaryExpression>(PositioningStrategy.ASSIGNMENT_LHS) {
|
val SETTER_PROJECTED_OUT by error<KtBinaryExpression>(PositioningStrategy.SELECTOR_BY_QUALIFIED) {
|
||||||
parameter<FirPropertySymbol>("property")
|
parameter<FirPropertySymbol>("property")
|
||||||
}
|
}
|
||||||
val WRONG_INVOCATION_KIND by warning<PsiElement> {
|
val WRONG_INVOCATION_KIND by warning<PsiElement> {
|
||||||
|
|||||||
-1
@@ -90,7 +90,6 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
|||||||
NAME_IDENTIFIER,
|
NAME_IDENTIFIER,
|
||||||
QUESTION_MARK_BY_TYPE,
|
QUESTION_MARK_BY_TYPE,
|
||||||
ANNOTATION_USE_SITE,
|
ANNOTATION_USE_SITE,
|
||||||
ASSIGNMENT_LHS,
|
|
||||||
IMPORT_LAST_NAME,
|
IMPORT_LAST_NAME,
|
||||||
DATA_MODIFIER,
|
DATA_MODIFIER,
|
||||||
SPREAD_OPERATOR,
|
SPREAD_OPERATOR,
|
||||||
|
|||||||
+2
-2
@@ -14,8 +14,8 @@ object JsExpressionCheckers : ExpressionCheckers() {
|
|||||||
FirJsQualifierChecker,
|
FirJsQualifierChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker>
|
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirJsDefinedExternallyCallChecker,
|
FirJsDefinedExternallyCallChecker
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-6
@@ -9,17 +9,20 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
|||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.closestNonLocal
|
import org.jetbrains.kotlin.fir.analysis.checkers.closestNonLocal
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeObject
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeObject
|
||||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.isPredefinedObject
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.isPredefinedObject
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.calleeReference
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
import org.jetbrains.kotlin.name.JsStandardClassIds
|
import org.jetbrains.kotlin.name.JsStandardClassIds
|
||||||
|
|
||||||
object FirJsDefinedExternallyCallChecker : FirQualifiedAccessChecker() {
|
object FirJsDefinedExternallyCallChecker : FirBasicExpressionChecker() {
|
||||||
override fun check(expression: FirQualifiedAccess, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val symbol = expression.calleeReference.toResolvedCallableSymbol() ?: return
|
val symbol = expression.calleeReference?.toResolvedCallableSymbol() ?: return
|
||||||
|
|
||||||
if (symbol.callableId !in JsStandardClassIds.Callables.definedExternallyPropertyNames) {
|
if (symbol.callableId !in JsStandardClassIds.Callables.definedExternallyPropertyNames) {
|
||||||
return
|
return
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
|
|||||||
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.*
|
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.*
|
||||||
|
|
||||||
object JvmExpressionCheckers : ExpressionCheckers() {
|
object JvmExpressionCheckers : ExpressionCheckers() {
|
||||||
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker>
|
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirJvmProtectedInSuperClassCompanionCallChecker
|
FirJvmProtectedInSuperClassCompanionCallChecker
|
||||||
)
|
)
|
||||||
|
|||||||
+15
-10
@@ -6,20 +6,19 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression
|
package org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingDeclarationSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingDeclarationSymbol
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
|
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
@@ -29,12 +28,18 @@ import org.jetbrains.kotlin.fir.types.typeContext
|
|||||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_CLASS_ID
|
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_CLASS_ID
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
|
|
||||||
object FirJvmProtectedInSuperClassCompanionCallChecker : FirQualifiedAccessChecker() {
|
object FirJvmProtectedInSuperClassCompanionCallChecker : FirBasicExpressionChecker() {
|
||||||
override fun check(expression: FirQualifiedAccess, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val dispatchReceiver = expression.dispatchReceiver
|
val dispatchReceiver = when (expression) {
|
||||||
|
is FirQualifiedAccessExpression -> expression.dispatchReceiver
|
||||||
|
is FirVariableAssignment -> expression.dispatchReceiver
|
||||||
|
else -> null
|
||||||
|
} ?: return
|
||||||
|
|
||||||
if (dispatchReceiver is FirNoReceiverExpression) return
|
if (dispatchReceiver is FirNoReceiverExpression) return
|
||||||
val dispatchClassSymbol = dispatchReceiver.typeRef.toRegularClassSymbol(context.session) ?: return
|
val dispatchClassSymbol = dispatchReceiver.typeRef.toRegularClassSymbol(context.session) ?: return
|
||||||
val resolvedSymbol = expression.calleeReference.toResolvedCallableSymbol() ?: return
|
val calleeReference = expression.calleeReference
|
||||||
|
val resolvedSymbol = calleeReference?.toResolvedCallableSymbol() ?: return
|
||||||
|
|
||||||
val visibility = if (resolvedSymbol is FirPropertySymbol) {
|
val visibility = if (resolvedSymbol is FirPropertySymbol) {
|
||||||
if (expression is FirVariableAssignment)
|
if (expression is FirVariableAssignment)
|
||||||
@@ -64,7 +69,7 @@ object FirJvmProtectedInSuperClassCompanionCallChecker : FirQualifiedAccessCheck
|
|||||||
it.symbol == dispatchClassSymbol || it.symbol == companionContainingClassSymbol
|
it.symbol == dispatchClassSymbol || it.symbol == companionContainingClassSymbol
|
||||||
} == null
|
} == null
|
||||||
) {
|
) {
|
||||||
reporter.reportOn(expression.calleeReference.source, FirJvmErrors.SUBCLASS_CANT_CALL_COMPANION_PROTECTED_NON_STATIC, context)
|
reporter.reportOn(calleeReference.source, FirJvmErrors.SUBCLASS_CANT_CALL_COMPANION_PROTECTED_NON_STATIC, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ object FirJvmSuspensionPointInsideMutexLockChecker : FirFunctionCallChecker() {
|
|||||||
if (!symbol.isSuspend) return
|
if (!symbol.isSuspend) return
|
||||||
val closestAnonymousFunction = context.findClosest<FirAnonymousFunction>() ?: return
|
val closestAnonymousFunction = context.findClosest<FirAnonymousFunction>() ?: return
|
||||||
|
|
||||||
for (call in context.qualifiedAccessOrAnnotationCalls.asReversed()) {
|
for (call in context.qualifiedAccessOrAssignmentsOrAnnotationCalls.asReversed()) {
|
||||||
if (call is FirFunctionCall) {
|
if (call is FirFunctionCall) {
|
||||||
val callableSymbol = call.calleeReference.toResolvedCallableSymbol() ?: continue
|
val callableSymbol = call.calleeReference.toResolvedCallableSymbol() ?: continue
|
||||||
if (callableSymbol.callableId == synchronizedCallableId) {
|
if (callableSymbol.callableId == synchronizedCallableId) {
|
||||||
|
|||||||
-4
@@ -15,8 +15,6 @@ import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
|
|||||||
class ComposedExpressionCheckers : ExpressionCheckers() {
|
class ComposedExpressionCheckers : ExpressionCheckers() {
|
||||||
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
|
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
|
||||||
get() = _basicExpressionCheckers
|
get() = _basicExpressionCheckers
|
||||||
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker>
|
|
||||||
get() = _qualifiedAccessCheckers
|
|
||||||
override val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker>
|
override val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker>
|
||||||
get() = _qualifiedAccessExpressionCheckers
|
get() = _qualifiedAccessExpressionCheckers
|
||||||
override val callCheckers: Set<FirCallChecker>
|
override val callCheckers: Set<FirCallChecker>
|
||||||
@@ -81,7 +79,6 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
|
|||||||
get() = _classReferenceExpressionCheckers
|
get() = _classReferenceExpressionCheckers
|
||||||
|
|
||||||
private val _basicExpressionCheckers: MutableSet<FirBasicExpressionChecker> = mutableSetOf()
|
private val _basicExpressionCheckers: MutableSet<FirBasicExpressionChecker> = mutableSetOf()
|
||||||
private val _qualifiedAccessCheckers: MutableSet<FirQualifiedAccessChecker> = mutableSetOf()
|
|
||||||
private val _qualifiedAccessExpressionCheckers: MutableSet<FirQualifiedAccessExpressionChecker> = mutableSetOf()
|
private val _qualifiedAccessExpressionCheckers: MutableSet<FirQualifiedAccessExpressionChecker> = mutableSetOf()
|
||||||
private val _callCheckers: MutableSet<FirCallChecker> = mutableSetOf()
|
private val _callCheckers: MutableSet<FirCallChecker> = mutableSetOf()
|
||||||
private val _functionCallCheckers: MutableSet<FirFunctionCallChecker> = mutableSetOf()
|
private val _functionCallCheckers: MutableSet<FirFunctionCallChecker> = mutableSetOf()
|
||||||
@@ -117,7 +114,6 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
|
|||||||
@CheckersComponentInternal
|
@CheckersComponentInternal
|
||||||
fun register(checkers: ExpressionCheckers) {
|
fun register(checkers: ExpressionCheckers) {
|
||||||
_basicExpressionCheckers += checkers.basicExpressionCheckers
|
_basicExpressionCheckers += checkers.basicExpressionCheckers
|
||||||
_qualifiedAccessCheckers += checkers.qualifiedAccessCheckers
|
|
||||||
_qualifiedAccessExpressionCheckers += checkers.qualifiedAccessExpressionCheckers
|
_qualifiedAccessExpressionCheckers += checkers.qualifiedAccessExpressionCheckers
|
||||||
_callCheckers += checkers.callCheckers
|
_callCheckers += checkers.callCheckers
|
||||||
_functionCallCheckers += checkers.functionCallCheckers
|
_functionCallCheckers += checkers.functionCallCheckers
|
||||||
|
|||||||
+7
-9
@@ -18,7 +18,6 @@ abstract class ExpressionCheckers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open val basicExpressionCheckers: Set<FirBasicExpressionChecker> = emptySet()
|
open val basicExpressionCheckers: Set<FirBasicExpressionChecker> = emptySet()
|
||||||
open val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker> = emptySet()
|
|
||||||
open val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> = emptySet()
|
open val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> = emptySet()
|
||||||
open val callCheckers: Set<FirCallChecker> = emptySet()
|
open val callCheckers: Set<FirCallChecker> = emptySet()
|
||||||
open val functionCallCheckers: Set<FirFunctionCallChecker> = emptySet()
|
open val functionCallCheckers: Set<FirFunctionCallChecker> = emptySet()
|
||||||
@@ -52,13 +51,12 @@ abstract class ExpressionCheckers {
|
|||||||
open val classReferenceExpressionCheckers: Set<FirClassReferenceExpressionChecker> = emptySet()
|
open val classReferenceExpressionCheckers: Set<FirClassReferenceExpressionChecker> = emptySet()
|
||||||
|
|
||||||
@CheckersComponentInternal internal val allBasicExpressionCheckers: Set<FirBasicExpressionChecker> by lazy { basicExpressionCheckers }
|
@CheckersComponentInternal internal val allBasicExpressionCheckers: Set<FirBasicExpressionChecker> by lazy { basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allQualifiedAccessCheckers: Set<FirQualifiedAccessChecker> by lazy { qualifiedAccessCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allQualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> by lazy { qualifiedAccessExpressionCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allQualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> by lazy { qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers }
|
|
||||||
@CheckersComponentInternal internal val allCallCheckers: Set<FirCallChecker> by lazy { callCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allCallCheckers: Set<FirCallChecker> by lazy { callCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allFunctionCallCheckers: Set<FirFunctionCallChecker> by lazy { functionCallCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers + callCheckers }
|
@CheckersComponentInternal internal val allFunctionCallCheckers: Set<FirFunctionCallChecker> by lazy { functionCallCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + callCheckers }
|
||||||
@CheckersComponentInternal internal val allPropertyAccessExpressionCheckers: Set<FirPropertyAccessExpressionChecker> by lazy { propertyAccessExpressionCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers }
|
@CheckersComponentInternal internal val allPropertyAccessExpressionCheckers: Set<FirPropertyAccessExpressionChecker> by lazy { propertyAccessExpressionCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allIntegerLiteralOperatorCallCheckers: Set<FirIntegerLiteralOperatorCallChecker> by lazy { integerLiteralOperatorCallCheckers + functionCallCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers + callCheckers }
|
@CheckersComponentInternal internal val allIntegerLiteralOperatorCallCheckers: Set<FirIntegerLiteralOperatorCallChecker> by lazy { integerLiteralOperatorCallCheckers + functionCallCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + callCheckers }
|
||||||
@CheckersComponentInternal internal val allVariableAssignmentCheckers: Set<FirVariableAssignmentChecker> by lazy { variableAssignmentCheckers + qualifiedAccessCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allVariableAssignmentCheckers: Set<FirVariableAssignmentChecker> by lazy { variableAssignmentCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allTryExpressionCheckers: Set<FirTryExpressionChecker> by lazy { tryExpressionCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allTryExpressionCheckers: Set<FirTryExpressionChecker> by lazy { tryExpressionCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allWhenExpressionCheckers: Set<FirWhenExpressionChecker> by lazy { whenExpressionCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allWhenExpressionCheckers: Set<FirWhenExpressionChecker> by lazy { whenExpressionCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allLoopExpressionCheckers: Set<FirLoopExpressionChecker> by lazy { loopExpressionCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allLoopExpressionCheckers: Set<FirLoopExpressionChecker> by lazy { loopExpressionCheckers + basicExpressionCheckers }
|
||||||
@@ -77,8 +75,8 @@ abstract class ExpressionCheckers {
|
|||||||
@CheckersComponentInternal internal val allTypeOperatorCallCheckers: Set<FirTypeOperatorCallChecker> by lazy { typeOperatorCallCheckers + basicExpressionCheckers + callCheckers }
|
@CheckersComponentInternal internal val allTypeOperatorCallCheckers: Set<FirTypeOperatorCallChecker> by lazy { typeOperatorCallCheckers + basicExpressionCheckers + callCheckers }
|
||||||
@CheckersComponentInternal internal val allResolvedQualifierCheckers: Set<FirResolvedQualifierChecker> by lazy { resolvedQualifierCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allResolvedQualifierCheckers: Set<FirResolvedQualifierChecker> by lazy { resolvedQualifierCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allConstExpressionCheckers: Set<FirConstExpressionChecker> by lazy { constExpressionCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allConstExpressionCheckers: Set<FirConstExpressionChecker> by lazy { constExpressionCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allCallableReferenceAccessCheckers: Set<FirCallableReferenceAccessChecker> by lazy { callableReferenceAccessCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers }
|
@CheckersComponentInternal internal val allCallableReferenceAccessCheckers: Set<FirCallableReferenceAccessChecker> by lazy { callableReferenceAccessCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allThisReceiverExpressionCheckers: Set<FirThisReceiverExpressionChecker> by lazy { thisReceiverExpressionCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers }
|
@CheckersComponentInternal internal val allThisReceiverExpressionCheckers: Set<FirThisReceiverExpressionChecker> by lazy { thisReceiverExpressionCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allWhileLoopCheckers: Set<FirWhileLoopChecker> by lazy { whileLoopCheckers + loopExpressionCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allWhileLoopCheckers: Set<FirWhileLoopChecker> by lazy { whileLoopCheckers + loopExpressionCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allThrowExpressionCheckers: Set<FirThrowExpressionChecker> by lazy { throwExpressionCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allThrowExpressionCheckers: Set<FirThrowExpressionChecker> by lazy { throwExpressionCheckers + basicExpressionCheckers }
|
||||||
@CheckersComponentInternal internal val allDoWhileLoopCheckers: Set<FirDoWhileLoopChecker> by lazy { doWhileLoopCheckers + loopExpressionCheckers + basicExpressionCheckers }
|
@CheckersComponentInternal internal val allDoWhileLoopCheckers: Set<FirDoWhileLoopChecker> by lazy { doWhileLoopCheckers + loopExpressionCheckers + basicExpressionCheckers }
|
||||||
|
|||||||
-2
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirLoop
|
import org.jetbrains.kotlin.fir.expressions.FirLoop
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirLoopJump
|
import org.jetbrains.kotlin.fir.expressions.FirLoopJump
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||||
@@ -45,7 +44,6 @@ import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
|
import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
|
||||||
|
|
||||||
typealias FirBasicExpressionChecker = FirExpressionChecker<FirStatement>
|
typealias FirBasicExpressionChecker = FirExpressionChecker<FirStatement>
|
||||||
typealias FirQualifiedAccessChecker = FirExpressionChecker<FirQualifiedAccess>
|
|
||||||
typealias FirQualifiedAccessExpressionChecker = FirExpressionChecker<FirQualifiedAccessExpression>
|
typealias FirQualifiedAccessExpressionChecker = FirExpressionChecker<FirQualifiedAccessExpression>
|
||||||
typealias FirCallChecker = FirExpressionChecker<FirCall>
|
typealias FirCallChecker = FirExpressionChecker<FirCall>
|
||||||
typealias FirFunctionCallChecker = FirExpressionChecker<FirFunctionCall>
|
typealias FirFunctionCallChecker = FirExpressionChecker<FirFunctionCall>
|
||||||
|
|||||||
+5
-5
@@ -123,7 +123,7 @@ object FirErrors {
|
|||||||
val BREAK_OR_CONTINUE_OUTSIDE_A_LOOP by error0<PsiElement>()
|
val BREAK_OR_CONTINUE_OUTSIDE_A_LOOP by error0<PsiElement>()
|
||||||
val NOT_A_LOOP_LABEL by error0<PsiElement>()
|
val NOT_A_LOOP_LABEL by error0<PsiElement>()
|
||||||
val BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY by error0<KtExpressionWithLabel>()
|
val BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY by error0<KtExpressionWithLabel>()
|
||||||
val VARIABLE_EXPECTED by error0<PsiElement>(SourceElementPositioningStrategies.ASSIGNMENT_LHS)
|
val VARIABLE_EXPECTED by error0<PsiElement>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||||
val DELEGATION_IN_INTERFACE by error0<PsiElement>()
|
val DELEGATION_IN_INTERFACE by error0<PsiElement>()
|
||||||
val DELEGATION_NOT_TO_INTERFACE by error0<PsiElement>()
|
val DELEGATION_NOT_TO_INTERFACE by error0<PsiElement>()
|
||||||
val NESTED_CLASS_NOT_ALLOWED by error1<KtNamedDeclaration, String>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
val NESTED_CLASS_NOT_ALLOWED by error1<KtNamedDeclaration, String>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
@@ -140,7 +140,7 @@ object FirErrors {
|
|||||||
val VAL_OR_VAR_ON_FUN_PARAMETER by error1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
val VAL_OR_VAR_ON_FUN_PARAMETER by error1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||||
val VAL_OR_VAR_ON_CATCH_PARAMETER by error1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
val VAL_OR_VAR_ON_CATCH_PARAMETER by error1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||||
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by error1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by error1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||||
val INVISIBLE_SETTER by error3<PsiElement, FirPropertySymbol, Visibility, CallableId>(SourceElementPositioningStrategies.ASSIGNMENT_LHS)
|
val INVISIBLE_SETTER by error3<PsiElement, FirPropertySymbol, Visibility, CallableId>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||||
|
|
||||||
// Unresolved
|
// Unresolved
|
||||||
val INVISIBLE_REFERENCE by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val INVISIBLE_REFERENCE by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
@@ -607,11 +607,11 @@ object FirErrors {
|
|||||||
val UNINITIALIZED_PARAMETER by error1<KtSimpleNameExpression, FirValueParameterSymbol>()
|
val UNINITIALIZED_PARAMETER by error1<KtSimpleNameExpression, FirValueParameterSymbol>()
|
||||||
val UNINITIALIZED_ENUM_ENTRY by error1<KtSimpleNameExpression, FirEnumEntrySymbol>()
|
val UNINITIALIZED_ENUM_ENTRY by error1<KtSimpleNameExpression, FirEnumEntrySymbol>()
|
||||||
val UNINITIALIZED_ENUM_COMPANION by error1<KtExpression, FirRegularClassSymbol>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val UNINITIALIZED_ENUM_COMPANION by error1<KtExpression, FirRegularClassSymbol>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
val VAL_REASSIGNMENT by error1<KtExpression, FirVariableSymbol<*>>()
|
val VAL_REASSIGNMENT by error1<KtExpression, FirVariableSymbol<*>>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||||
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by deprecationError1<KtExpression, FirBackingFieldSymbol>(RestrictionOfValReassignmentViaBackingField)
|
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by deprecationError1<KtExpression, FirBackingFieldSymbol>(RestrictionOfValReassignmentViaBackingField, SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||||
val CAPTURED_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>()
|
val CAPTURED_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>()
|
||||||
val CAPTURED_MEMBER_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>()
|
val CAPTURED_MEMBER_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>()
|
||||||
val SETTER_PROJECTED_OUT by error1<KtBinaryExpression, FirPropertySymbol>(SourceElementPositioningStrategies.ASSIGNMENT_LHS)
|
val SETTER_PROJECTED_OUT by error1<KtBinaryExpression, FirPropertySymbol>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||||
val WRONG_INVOCATION_KIND by warning3<PsiElement, FirBasedSymbol<*>, EventOccurrencesRange, EventOccurrencesRange>()
|
val WRONG_INVOCATION_KIND by warning3<PsiElement, FirBasedSymbol<*>, EventOccurrencesRange, EventOccurrencesRange>()
|
||||||
val LEAKED_IN_PLACE_LAMBDA by warning1<PsiElement, FirBasedSymbol<*>>()
|
val LEAKED_IN_PLACE_LAMBDA by warning1<PsiElement, FirBasedSymbol<*>>()
|
||||||
val WRONG_IMPLIES_CONDITION by warning0<PsiElement>()
|
val WRONG_IMPLIES_CONDITION by warning0<PsiElement>()
|
||||||
|
|||||||
+2
-5
@@ -22,11 +22,8 @@ import org.jetbrains.kotlin.fir.contracts.effects
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner
|
import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
|
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
|
||||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||||
@@ -309,7 +306,7 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() {
|
|||||||
return this is FirAnonymousFunction && this.isLambda && this.invocationKind != null
|
return this is FirAnonymousFunction && this.isLambda && this.invocationKind != null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirExpression?.toQualifiedReference(): FirReference? = (this as? FirQualifiedAccess)?.calleeReference
|
private fun FirExpression?.toQualifiedReference(): FirReference? = (this as? FirQualifiedAccessExpression)?.calleeReference
|
||||||
|
|
||||||
private fun referenceToSymbol(reference: FirReference?): FirBasedSymbol<*>? = when (reference) {
|
private fun referenceToSymbol(reference: FirReference?): FirBasedSymbol<*>? = when (reference) {
|
||||||
is FirResolvedNamedReference -> reference.resolvedSymbol
|
is FirResolvedNamedReference -> reference.resolvedSymbol
|
||||||
|
|||||||
+9
-7
@@ -18,8 +18,10 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
|
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField
|
import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isLateInit
|
import org.jetbrains.kotlin.fir.declarations.utils.isLateInit
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.calleeReference
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.unwrapLValue
|
||||||
import org.jetbrains.kotlin.fir.isCatchParameter
|
import org.jetbrains.kotlin.fir.isCatchParameter
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
||||||
@@ -65,7 +67,7 @@ private fun PropertyInitializationInfoData.checkPropertyAccesses(
|
|||||||
scope: FirDeclaration?,
|
scope: FirDeclaration?,
|
||||||
scopes: MutableMap<FirPropertySymbol, FirDeclaration?>,
|
scopes: MutableMap<FirPropertySymbol, FirDeclaration?>,
|
||||||
) {
|
) {
|
||||||
fun FirQualifiedAccess.hasCorrectReceiver() =
|
fun FirQualifiedAccessExpression.hasCorrectReceiver() =
|
||||||
(dispatchReceiver as? FirThisReceiverExpression)?.calleeReference?.boundSymbol == receiver
|
(dispatchReceiver as? FirThisReceiverExpression)?.calleeReference?.boundSymbol == receiver
|
||||||
|
|
||||||
for (node in graph.nodes) {
|
for (node in graph.nodes) {
|
||||||
@@ -83,17 +85,17 @@ private fun PropertyInitializationInfoData.checkPropertyAccesses(
|
|||||||
}
|
}
|
||||||
|
|
||||||
node is VariableAssignmentNode -> {
|
node is VariableAssignmentNode -> {
|
||||||
val symbol = node.fir.calleeReference.toResolvedPropertySymbol() ?: continue
|
val symbol = node.fir.calleeReference?.toResolvedPropertySymbol() ?: continue
|
||||||
if (!symbol.fir.isVal || !node.fir.hasCorrectReceiver() || symbol !in properties) continue
|
if (!symbol.fir.isVal || node.fir.unwrapLValue()?.hasCorrectReceiver() != true || symbol !in properties) continue
|
||||||
|
|
||||||
if (scope != scopes[symbol]) {
|
if (getValue(node).values.any { it[symbol]?.canBeRevisited() == true }) {
|
||||||
|
reporter.reportOn(node.fir.lValue.source, FirErrors.VAL_REASSIGNMENT, symbol, context)
|
||||||
|
} else if (scope != scopes[symbol]) {
|
||||||
val error = if (receiver != null)
|
val error = if (receiver != null)
|
||||||
FirErrors.CAPTURED_MEMBER_VAL_INITIALIZATION
|
FirErrors.CAPTURED_MEMBER_VAL_INITIALIZATION
|
||||||
else
|
else
|
||||||
FirErrors.CAPTURED_VAL_INITIALIZATION
|
FirErrors.CAPTURED_VAL_INITIALIZATION
|
||||||
reporter.reportOn(node.fir.lValue.source, error, symbol, context)
|
reporter.reportOn(node.fir.lValue.source, error, symbol, context)
|
||||||
} else if (getValue(node).values.any { it[symbol]?.canBeRevisited() == true }) {
|
|
||||||
reporter.reportOn(node.fir.lValue.source, FirErrors.VAL_REASSIGNMENT, symbol, context)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.fir.analysis.cfa.util
|
|||||||
import kotlinx.collections.immutable.persistentMapOf
|
import kotlinx.collections.immutable.persistentMapOf
|
||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.calleeReference
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.dispatchReceiver
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
@@ -51,7 +53,7 @@ class PropertyInitializationInfoCollector(
|
|||||||
val dataForNode = visitNode(node, data)
|
val dataForNode = visitNode(node, data)
|
||||||
val receiver = (node.fir.dispatchReceiver as? FirThisReceiverExpression)?.calleeReference?.boundSymbol
|
val receiver = (node.fir.dispatchReceiver as? FirThisReceiverExpression)?.calleeReference?.boundSymbol
|
||||||
if (receiver != expectedReceiver) return dataForNode
|
if (receiver != expectedReceiver) return dataForNode
|
||||||
val symbol = node.fir.calleeReference.toResolvedPropertySymbol() ?: return dataForNode
|
val symbol = node.fir.calleeReference?.toResolvedPropertySymbol() ?: return dataForNode
|
||||||
if (symbol !in localProperties) return dataForNode
|
if (symbol !in localProperties) return dataForNode
|
||||||
return addRange(dataForNode, symbol, EventOccurrencesRange.EXACTLY_ONCE)
|
return addRange(dataForNode, symbol, EventOccurrencesRange.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-7
@@ -22,7 +22,8 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
FirUnderscoreChecker,
|
FirUnderscoreChecker,
|
||||||
FirExpressionAnnotationChecker,
|
FirExpressionAnnotationChecker,
|
||||||
FirDeprecationChecker,
|
FirDeprecationChecker,
|
||||||
FirRecursiveProblemChecker
|
FirRecursiveProblemChecker,
|
||||||
|
FirOptInUsageAccessChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val throwExpressionCheckers: Set<FirThrowExpressionChecker>
|
override val throwExpressionCheckers: Set<FirThrowExpressionChecker>
|
||||||
@@ -30,11 +31,6 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
FirThrowExpressionTypeChecker,
|
FirThrowExpressionTypeChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker>
|
|
||||||
get() = setOf(
|
|
||||||
FirOptInUsageAccessChecker,
|
|
||||||
)
|
|
||||||
|
|
||||||
override val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker>
|
override val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirCallableReferenceChecker,
|
FirCallableReferenceChecker,
|
||||||
@@ -83,7 +79,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker>
|
override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirReassignmentAndInvisibleSetterChecker,
|
FirReassignmentAndInvisibleSetterChecker,
|
||||||
FirAssignmentTypeMismatchChecker
|
FirAssignmentTypeMismatchChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val whenExpressionCheckers: Set<FirWhenExpressionChecker>
|
override val whenExpressionCheckers: Set<FirWhenExpressionChecker>
|
||||||
|
|||||||
@@ -655,7 +655,7 @@ fun getActualTargetList(annotated: FirDeclaration): AnnotationTargetList {
|
|||||||
|
|
||||||
private typealias TargetLists = AnnotationTargetLists
|
private typealias TargetLists = AnnotationTargetLists
|
||||||
|
|
||||||
fun FirQualifiedAccess.explicitReceiverIsNotSuperReference(): Boolean {
|
fun FirQualifiedAccessExpression.explicitReceiverIsNotSuperReference(): Boolean {
|
||||||
return (this.explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference !is FirSuperReference
|
return (this.explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference !is FirSuperReference
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,3 +728,9 @@ fun FirBasedSymbol<*>.getAnnotationStringParameter(classId: ClassId, session: Fi
|
|||||||
val expression = annotation?.argumentMapping?.mapping?.values?.firstOrNull() as? FirConstExpression<*>
|
val expression = annotation?.argumentMapping?.mapping?.values?.firstOrNull() as? FirConstExpression<*>
|
||||||
return expression?.value as? String
|
return expression?.value as? String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirElement.isLhsOfAssignment(context: CheckerContext): Boolean {
|
||||||
|
if (this !is FirQualifiedAccessExpression) return false
|
||||||
|
val lastQualified = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.lastOrNull { it != this } ?: return false
|
||||||
|
return lastQualified is FirVariableAssignment && lastQualified.lValue == this
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ abstract class CheckerContext : MutableDiagnosticContext() {
|
|||||||
// Context
|
// Context
|
||||||
abstract val implicitReceiverStack: ImplicitReceiverStack
|
abstract val implicitReceiverStack: ImplicitReceiverStack
|
||||||
abstract val containingDeclarations: List<FirDeclaration>
|
abstract val containingDeclarations: List<FirDeclaration>
|
||||||
abstract val qualifiedAccessOrAnnotationCalls: List<FirStatement>
|
abstract val qualifiedAccessOrAssignmentsOrAnnotationCalls: List<FirStatement>
|
||||||
abstract val getClassCalls: List<FirGetClassCall>
|
abstract val getClassCalls: List<FirGetClassCall>
|
||||||
abstract val annotationContainers: List<FirAnnotationContainer>
|
abstract val annotationContainers: List<FirAnnotationContainer>
|
||||||
abstract val isContractBody: Boolean
|
abstract val isContractBody: Boolean
|
||||||
|
|||||||
+5
-5
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
class MutableCheckerContext private constructor(
|
class MutableCheckerContext private constructor(
|
||||||
override val implicitReceiverStack: PersistentImplicitReceiverStack,
|
override val implicitReceiverStack: PersistentImplicitReceiverStack,
|
||||||
override val containingDeclarations: MutableList<FirDeclaration>,
|
override val containingDeclarations: MutableList<FirDeclaration>,
|
||||||
override val qualifiedAccessOrAnnotationCalls: MutableList<FirStatement>,
|
override val qualifiedAccessOrAssignmentsOrAnnotationCalls: MutableList<FirStatement>,
|
||||||
override val getClassCalls: MutableList<FirGetClassCall>,
|
override val getClassCalls: MutableList<FirGetClassCall>,
|
||||||
override val annotationContainers: MutableList<FirAnnotationContainer>,
|
override val annotationContainers: MutableList<FirAnnotationContainer>,
|
||||||
override var isContractBody: Boolean,
|
override var isContractBody: Boolean,
|
||||||
@@ -50,7 +50,7 @@ class MutableCheckerContext private constructor(
|
|||||||
return MutableCheckerContext(
|
return MutableCheckerContext(
|
||||||
implicitReceiverStack.add(name, value),
|
implicitReceiverStack.add(name, value),
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
qualifiedAccessOrAnnotationCalls,
|
qualifiedAccessOrAssignmentsOrAnnotationCalls,
|
||||||
getClassCalls,
|
getClassCalls,
|
||||||
annotationContainers,
|
annotationContainers,
|
||||||
isContractBody,
|
isContractBody,
|
||||||
@@ -73,12 +73,12 @@ class MutableCheckerContext private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): MutableCheckerContext {
|
override fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): MutableCheckerContext {
|
||||||
qualifiedAccessOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall)
|
qualifiedAccessOrAssignmentsOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dropQualifiedAccessOrAnnotationCall() {
|
override fun dropQualifiedAccessOrAnnotationCall() {
|
||||||
qualifiedAccessOrAnnotationCalls.removeAt(qualifiedAccessOrAnnotationCalls.size - 1)
|
qualifiedAccessOrAssignmentsOrAnnotationCalls.removeAt(qualifiedAccessOrAssignmentsOrAnnotationCalls.size - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addGetClassCall(getClassCall: FirGetClassCall): MutableCheckerContext {
|
override fun addGetClassCall(getClassCall: FirGetClassCall): MutableCheckerContext {
|
||||||
@@ -109,7 +109,7 @@ class MutableCheckerContext private constructor(
|
|||||||
return MutableCheckerContext(
|
return MutableCheckerContext(
|
||||||
implicitReceiverStack,
|
implicitReceiverStack,
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
qualifiedAccessOrAnnotationCalls,
|
qualifiedAccessOrAssignmentsOrAnnotationCalls,
|
||||||
getClassCalls,
|
getClassCalls,
|
||||||
annotationContainers,
|
annotationContainers,
|
||||||
isContractBody,
|
isContractBody,
|
||||||
|
|||||||
+8
-8
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
class PersistentCheckerContext private constructor(
|
class PersistentCheckerContext private constructor(
|
||||||
override val implicitReceiverStack: PersistentImplicitReceiverStack,
|
override val implicitReceiverStack: PersistentImplicitReceiverStack,
|
||||||
override val containingDeclarations: PersistentList<FirDeclaration>,
|
override val containingDeclarations: PersistentList<FirDeclaration>,
|
||||||
override val qualifiedAccessOrAnnotationCalls: PersistentList<FirStatement>,
|
override val qualifiedAccessOrAssignmentsOrAnnotationCalls: PersistentList<FirStatement>,
|
||||||
override val getClassCalls: PersistentList<FirGetClassCall>,
|
override val getClassCalls: PersistentList<FirGetClassCall>,
|
||||||
override val annotationContainers: PersistentList<FirAnnotationContainer>,
|
override val annotationContainers: PersistentList<FirAnnotationContainer>,
|
||||||
override val isContractBody: Boolean,
|
override val isContractBody: Boolean,
|
||||||
@@ -52,7 +52,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
return PersistentCheckerContext(
|
return PersistentCheckerContext(
|
||||||
implicitReceiverStack.add(name, value),
|
implicitReceiverStack.add(name, value),
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
qualifiedAccessOrAnnotationCalls,
|
qualifiedAccessOrAssignmentsOrAnnotationCalls,
|
||||||
getClassCalls,
|
getClassCalls,
|
||||||
annotationContainers,
|
annotationContainers,
|
||||||
isContractBody,
|
isContractBody,
|
||||||
@@ -69,7 +69,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
return PersistentCheckerContext(
|
return PersistentCheckerContext(
|
||||||
implicitReceiverStack,
|
implicitReceiverStack,
|
||||||
containingDeclarations.add(declaration),
|
containingDeclarations.add(declaration),
|
||||||
qualifiedAccessOrAnnotationCalls,
|
qualifiedAccessOrAssignmentsOrAnnotationCalls,
|
||||||
getClassCalls,
|
getClassCalls,
|
||||||
annotationContainers,
|
annotationContainers,
|
||||||
isContractBody,
|
isContractBody,
|
||||||
@@ -89,7 +89,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
return PersistentCheckerContext(
|
return PersistentCheckerContext(
|
||||||
implicitReceiverStack,
|
implicitReceiverStack,
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
this.qualifiedAccessOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall),
|
this.qualifiedAccessOrAssignmentsOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall),
|
||||||
getClassCalls,
|
getClassCalls,
|
||||||
annotationContainers,
|
annotationContainers,
|
||||||
isContractBody,
|
isContractBody,
|
||||||
@@ -109,7 +109,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
return PersistentCheckerContext(
|
return PersistentCheckerContext(
|
||||||
implicitReceiverStack,
|
implicitReceiverStack,
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
qualifiedAccessOrAnnotationCalls,
|
qualifiedAccessOrAssignmentsOrAnnotationCalls,
|
||||||
getClassCalls.add(getClassCall),
|
getClassCalls.add(getClassCall),
|
||||||
annotationContainers,
|
annotationContainers,
|
||||||
isContractBody,
|
isContractBody,
|
||||||
@@ -129,7 +129,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
return PersistentCheckerContext(
|
return PersistentCheckerContext(
|
||||||
implicitReceiverStack,
|
implicitReceiverStack,
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
qualifiedAccessOrAnnotationCalls,
|
qualifiedAccessOrAssignmentsOrAnnotationCalls,
|
||||||
getClassCalls,
|
getClassCalls,
|
||||||
annotationContainers.add(annotationContainer),
|
annotationContainers.add(annotationContainer),
|
||||||
isContractBody,
|
isContractBody,
|
||||||
@@ -155,7 +155,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
return PersistentCheckerContext(
|
return PersistentCheckerContext(
|
||||||
implicitReceiverStack,
|
implicitReceiverStack,
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
qualifiedAccessOrAnnotationCalls,
|
qualifiedAccessOrAssignmentsOrAnnotationCalls,
|
||||||
getClassCalls,
|
getClassCalls,
|
||||||
annotationContainers,
|
annotationContainers,
|
||||||
isContractBody,
|
isContractBody,
|
||||||
@@ -174,7 +174,7 @@ class PersistentCheckerContext private constructor(
|
|||||||
return PersistentCheckerContext(
|
return PersistentCheckerContext(
|
||||||
implicitReceiverStack,
|
implicitReceiverStack,
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
qualifiedAccessOrAnnotationCalls,
|
qualifiedAccessOrAssignmentsOrAnnotationCalls,
|
||||||
getClassCalls,
|
getClassCalls,
|
||||||
annotationContainers,
|
annotationContainers,
|
||||||
isContractBody = newValue,
|
isContractBody = newValue,
|
||||||
|
|||||||
+1
-1
@@ -182,7 +182,7 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val FirExpression.explicitReceiverOfQualifiedAccess: FirQualifiedAccessExpression?
|
private val FirExpression.explicitReceiverOfQualifiedAccess: FirQualifiedAccessExpression?
|
||||||
get() = (this as? FirQualifiedAccess)?.explicitReceiver?.unwrapped as? FirQualifiedAccessExpression
|
get() = (this as? FirQualifiedAccessExpression)?.explicitReceiver?.unwrapped as? FirQualifiedAccessExpression
|
||||||
|
|
||||||
private val FirExpression.unwrapped: FirExpression
|
private val FirExpression.unwrapped: FirExpression
|
||||||
get() =
|
get() =
|
||||||
|
|||||||
+15
-10
@@ -111,7 +111,7 @@ abstract class FirInlineDeclarationChecker : FirFunctionChecker() {
|
|||||||
override fun visitSmartCastExpression(smartCastExpression: FirSmartCastExpression, data: CheckerContext) {}
|
override fun visitSmartCastExpression(smartCastExpression: FirSmartCastExpression, data: CheckerContext) {}
|
||||||
|
|
||||||
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: CheckerContext) {
|
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: CheckerContext) {
|
||||||
val propertySymbol = variableAssignment.calleeReference.toResolvedCallableSymbol() as? FirPropertySymbol ?: return
|
val propertySymbol = variableAssignment.calleeReference?.toResolvedCallableSymbol() as? FirPropertySymbol ?: return
|
||||||
val setterSymbol = propertySymbol.setterSymbol ?: return
|
val setterSymbol = propertySymbol.setterSymbol ?: return
|
||||||
checkQualifiedAccess(variableAssignment, setterSymbol, data)
|
checkQualifiedAccess(variableAssignment, setterSymbol, data)
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ abstract class FirInlineDeclarationChecker : FirFunctionChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkQualifiedAccess(
|
private fun checkQualifiedAccess(
|
||||||
qualifiedAccess: FirQualifiedAccess,
|
qualifiedAccess: FirStatement,
|
||||||
targetSymbol: FirBasedSymbol<*>?,
|
targetSymbol: FirBasedSymbol<*>?,
|
||||||
context: CheckerContext
|
context: CheckerContext
|
||||||
) {
|
) {
|
||||||
@@ -253,18 +253,18 @@ abstract class FirInlineDeclarationChecker : FirFunctionChecker() {
|
|||||||
checkRecursion(targetSymbol, source, context)
|
checkRecursion(targetSymbol, source, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirQualifiedAccess.partOfCall(context: CheckerContext): Boolean {
|
private fun FirStatement.partOfCall(context: CheckerContext): Boolean {
|
||||||
if (this !is FirExpression) return false
|
if (this !is FirExpression) return false
|
||||||
val containingQualifiedAccess = context.qualifiedAccessOrAnnotationCalls.getOrNull(
|
val containingQualifiedAccess = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.getOrNull(
|
||||||
context.qualifiedAccessOrAnnotationCalls.size - 2
|
context.qualifiedAccessOrAssignmentsOrAnnotationCalls.size - 2
|
||||||
) ?: return false
|
) ?: return false
|
||||||
if (this == (containingQualifiedAccess as? FirQualifiedAccess)?.explicitReceiver) return true
|
if (this == (containingQualifiedAccess as? FirQualifiedAccessExpression)?.explicitReceiver) return true
|
||||||
val call = containingQualifiedAccess as? FirCall ?: return false
|
val call = containingQualifiedAccess as? FirCall ?: return false
|
||||||
return call.arguments.any { it.unwrapArgument() == this }
|
return call.arguments.any { it.unwrapArgument() == this }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkVisibilityAndAccess(
|
private fun checkVisibilityAndAccess(
|
||||||
accessExpression: FirQualifiedAccess,
|
accessExpression: FirStatement,
|
||||||
calledDeclaration: FirCallableSymbol<*>?,
|
calledDeclaration: FirCallableSymbol<*>?,
|
||||||
source: KtSourceElement,
|
source: KtSourceElement,
|
||||||
context: CheckerContext
|
context: CheckerContext
|
||||||
@@ -321,16 +321,21 @@ abstract class FirInlineDeclarationChecker : FirFunctionChecker() {
|
|||||||
|
|
||||||
private fun checkSuperCalls(
|
private fun checkSuperCalls(
|
||||||
calledDeclaration: FirCallableSymbol<*>,
|
calledDeclaration: FirCallableSymbol<*>,
|
||||||
callExpression: FirQualifiedAccess,
|
callExpression: FirStatement,
|
||||||
context: CheckerContext
|
context: CheckerContext
|
||||||
) {
|
) {
|
||||||
val receiver = callExpression.dispatchReceiver as? FirQualifiedAccessExpression ?: return
|
val receiver = when (callExpression) {
|
||||||
|
is FirQualifiedAccessExpression -> callExpression.dispatchReceiver
|
||||||
|
is FirVariableAssignment -> callExpression.dispatchReceiver
|
||||||
|
else -> null
|
||||||
|
} as? FirQualifiedAccessExpression ?: return
|
||||||
|
|
||||||
if (receiver.calleeReference is FirSuperReference) {
|
if (receiver.calleeReference is FirSuperReference) {
|
||||||
val dispatchReceiverType = receiver.dispatchReceiver.typeRef.coneType
|
val dispatchReceiverType = receiver.dispatchReceiver.typeRef.coneType
|
||||||
val classSymbol = dispatchReceiverType.toSymbol(session) ?: return
|
val classSymbol = dispatchReceiverType.toSymbol(session) ?: return
|
||||||
if (!classSymbol.isDefinedInInlineFunction()) {
|
if (!classSymbol.isDefinedInInlineFunction()) {
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
callExpression.dispatchReceiver.source,
|
receiver.source,
|
||||||
FirErrors.SUPER_CALL_FROM_PUBLIC_INLINE,
|
FirErrors.SUPER_CALL_FROM_PUBLIC_INLINE,
|
||||||
calledDeclaration,
|
calledDeclaration,
|
||||||
context
|
context
|
||||||
|
|||||||
+2
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.calleeReference
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
@@ -38,7 +39,7 @@ object FirPropertyInitializationChecker : FirRegularClassChecker() {
|
|||||||
|
|
||||||
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment) {
|
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment) {
|
||||||
variableAssignment.acceptChildren(this)
|
variableAssignment.acceptChildren(this)
|
||||||
val propertySymbol = variableAssignment.lValue.toResolvedCallableSymbol() as? FirPropertySymbol ?: return
|
val propertySymbol = variableAssignment.calleeReference?.toResolvedCallableSymbol() as? FirPropertySymbol ?: return
|
||||||
if (propertySymbol !in declaredLater) return
|
if (propertySymbol !in declaredLater) return
|
||||||
reporter.reportOn(variableAssignment.lValue.source, FirErrors.INITIALIZATION_BEFORE_DECLARATION, propertySymbol, context)
|
reporter.reportOn(variableAssignment.lValue.source, FirErrors.INITIALIZATION_BEFORE_DECLARATION, propertySymbol, context)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.types.coneType
|
|||||||
object FirAssignmentTypeMismatchChecker : FirVariableAssignmentChecker() {
|
object FirAssignmentTypeMismatchChecker : FirVariableAssignmentChecker() {
|
||||||
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val source = expression.rValue.source ?: return
|
val source = expression.rValue.source ?: return
|
||||||
val coneType = expression.lValueTypeRef.coneType
|
val coneType = expression.lValue.typeRef.coneType
|
||||||
checkTypeMismatch(
|
checkTypeMismatch(
|
||||||
coneType,
|
coneType,
|
||||||
expression,
|
expression,
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ object FirConstructorCallChecker : FirFunctionCallChecker() {
|
|||||||
reporter.reportOn(expression.source, FirErrors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, context)
|
reporter.reportOn(expression.source, FirErrors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, context)
|
||||||
}
|
}
|
||||||
if (declarationClass.classKind == ClassKind.ANNOTATION_CLASS &&
|
if (declarationClass.classKind == ClassKind.ANNOTATION_CLASS &&
|
||||||
context.qualifiedAccessOrAnnotationCalls.all { call ->
|
context.qualifiedAccessOrAssignmentsOrAnnotationCalls.all { call ->
|
||||||
call !is FirAnnotation
|
call !is FirAnnotation
|
||||||
} &&
|
} &&
|
||||||
context.containingDeclarations.all { klass ->
|
context.containingDeclarations.all { klass ->
|
||||||
|
|||||||
+8
-8
@@ -15,11 +15,9 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.declarations.FutureApiDeprecationInfo
|
import org.jetbrains.kotlin.fir.declarations.FutureApiDeprecationInfo
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.isLhsOfAssignment
|
||||||
import org.jetbrains.kotlin.fir.declarations.getDeprecation
|
import org.jetbrains.kotlin.fir.declarations.getDeprecation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvable
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
|
||||||
import org.jetbrains.kotlin.fir.references.resolved
|
import org.jetbrains.kotlin.fir.references.resolved
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
@@ -36,11 +34,13 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
|
|||||||
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
if (!allowedSourceKinds.contains(expression.source?.kind)) return
|
if (!allowedSourceKinds.contains(expression.source?.kind)) return
|
||||||
if (expression is FirAnnotation || expression is FirDelegatedConstructorCall) return //checked by FirDeprecatedTypeChecker
|
if (expression is FirAnnotation || expression is FirDelegatedConstructorCall) return //checked by FirDeprecatedTypeChecker
|
||||||
val resolvable = expression as? FirResolvable ?: return
|
if (expression.isLhsOfAssignment(context)) return
|
||||||
val reference = resolvable.calleeReference.resolved ?: return
|
|
||||||
val referencedSymbol = reference.resolvedSymbol
|
|
||||||
|
|
||||||
reportApiStatusIfNeeded(reference.source, referencedSymbol, expression, context, reporter)
|
val calleeReference = expression.calleeReference ?: return
|
||||||
|
val resolvedReference = calleeReference.resolved ?: return
|
||||||
|
val referencedSymbol = resolvedReference.resolvedSymbol
|
||||||
|
|
||||||
|
reportApiStatusIfNeeded(resolvedReference.source, referencedSymbol, expression, context, reporter)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun reportApiStatusIfNeeded(
|
internal fun reportApiStatusIfNeeded(
|
||||||
|
|||||||
+19
-15
@@ -8,33 +8,37 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
|||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.analysis.checkers.isLhsOfAssignment
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
|
||||||
object FirOptInUsageAccessChecker : FirQualifiedAccessChecker() {
|
object FirOptInUsageAccessChecker : FirBasicExpressionChecker() {
|
||||||
override fun check(expression: FirQualifiedAccess, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val sourceKind = expression.source?.kind
|
val sourceKind = expression.source?.kind
|
||||||
if (sourceKind is KtFakeSourceElementKind.DataClassGeneratedMembers ||
|
if (sourceKind is KtFakeSourceElementKind.DataClassGeneratedMembers ||
|
||||||
sourceKind is KtFakeSourceElementKind.PropertyFromParameter
|
sourceKind is KtFakeSourceElementKind.PropertyFromParameter
|
||||||
) return
|
) return
|
||||||
val resolvedSymbol = expression.calleeReference.toResolvedBaseSymbol() ?: return
|
|
||||||
val dispatchReceiverType =
|
if (expression.isLhsOfAssignment(context)) return
|
||||||
expression.dispatchReceiver.takeIf { it !is FirNoReceiverExpression }?.typeRef?.coneType?.fullyExpandedType(context.session)
|
|
||||||
|
val resolvedSymbol = expression.calleeReference?.toResolvedBaseSymbol() ?: return
|
||||||
|
|
||||||
with(FirOptInUsageBaseChecker) {
|
with(FirOptInUsageBaseChecker) {
|
||||||
if (expression is FirVariableAssignment && resolvedSymbol is FirPropertySymbol) {
|
if (expression is FirVariableAssignment) {
|
||||||
val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = true, dispatchReceiverType) +
|
val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = true, null) +
|
||||||
loadExperimentalitiesFromTypeArguments(context, expression.typeArguments)
|
loadExperimentalitiesFromTypeArguments(context, emptyList())
|
||||||
reportNotAcceptedExperimentalities(experimentalities, expression.lValue, context, reporter)
|
reportNotAcceptedExperimentalities(experimentalities, expression.lValue, context, reporter)
|
||||||
return
|
} else if (expression is FirQualifiedAccessExpression) {
|
||||||
|
val dispatchReceiverType =
|
||||||
|
expression.dispatchReceiver.takeIf { it !is FirNoReceiverExpression }?.typeRef?.coneType?.fullyExpandedType(context.session)
|
||||||
|
|
||||||
|
val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = false, dispatchReceiverType) +
|
||||||
|
loadExperimentalitiesFromTypeArguments(context, expression.typeArguments)
|
||||||
|
reportNotAcceptedExperimentalities(experimentalities, expression, context, reporter)
|
||||||
}
|
}
|
||||||
val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = false, dispatchReceiverType) +
|
|
||||||
loadExperimentalitiesFromTypeArguments(context, expression.typeArguments)
|
|
||||||
reportNotAcceptedExperimentalities(experimentalities, expression, context, reporter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-17
@@ -16,17 +16,14 @@ import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
|
||||||
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
||||||
import org.jetbrains.kotlin.fir.references.FirBackingFieldReference
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedValueParameterSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ExpressionReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ExpressionReceiverValue
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithCandidates
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
import org.jetbrains.kotlin.fir.visibilityChecker
|
||||||
@@ -36,7 +33,7 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
|
|||||||
checkInvisibleSetter(expression, context, reporter)
|
checkInvisibleSetter(expression, context, reporter)
|
||||||
checkValReassignmentViaBackingField(expression, context, reporter)
|
checkValReassignmentViaBackingField(expression, context, reporter)
|
||||||
checkValReassignmentOnValueParameter(expression, context, reporter)
|
checkValReassignmentOnValueParameter(expression, context, reporter)
|
||||||
checkAssignmentToThis(expression, context, reporter)
|
checkVariableExpected(expression, context, reporter)
|
||||||
checkValReassignment(expression, context, reporter)
|
checkValReassignment(expression, context, reporter)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +58,7 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val callableSymbol = expression.calleeReference.toResolvedCallableSymbol()
|
val callableSymbol = expression.calleeReference?.toResolvedCallableSymbol()
|
||||||
if (callableSymbol is FirPropertySymbol && shouldInvisibleSetterBeReported(callableSymbol)) {
|
if (callableSymbol is FirPropertySymbol && shouldInvisibleSetterBeReported(callableSymbol)) {
|
||||||
val explicitReceiver = expression.explicitReceiver
|
val explicitReceiver = expression.explicitReceiver
|
||||||
// Try to get type from smartcast
|
// Try to get type from smartcast
|
||||||
@@ -78,7 +75,7 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
expression.source,
|
expression.lValue.source,
|
||||||
FirErrors.INVISIBLE_SETTER,
|
FirErrors.INVISIBLE_SETTER,
|
||||||
callableSymbol,
|
callableSymbol,
|
||||||
callableSymbol.setterSymbol?.visibility ?: Visibilities.Private,
|
callableSymbol.setterSymbol?.visibility ?: Visibilities.Private,
|
||||||
@@ -93,7 +90,7 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
|
|||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter
|
reporter: DiagnosticReporter
|
||||||
) {
|
) {
|
||||||
val backingFieldReference = expression.lValue as? FirBackingFieldReference ?: return
|
val backingFieldReference = expression.calleeReference as? FirBackingFieldReference ?: return
|
||||||
val propertySymbol = backingFieldReference.resolvedSymbol
|
val propertySymbol = backingFieldReference.resolvedSymbol
|
||||||
if (propertySymbol.isVar) return
|
if (propertySymbol.isVar) return
|
||||||
val closestGetter = context.findClosest<FirPropertyAccessor> { it.isGetter }?.symbol ?: return
|
val closestGetter = context.findClosest<FirPropertyAccessor> { it.isGetter }?.symbol ?: return
|
||||||
@@ -107,22 +104,37 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
|
|||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter
|
reporter: DiagnosticReporter
|
||||||
) {
|
) {
|
||||||
val valueParameter = expression.lValue.toResolvedValueParameterSymbol() ?: return
|
val valueParameter = expression.calleeReference?.toResolvedValueParameterSymbol() ?: return
|
||||||
reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, valueParameter, context)
|
reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, valueParameter, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkAssignmentToThis(
|
private fun checkVariableExpected(
|
||||||
expression: FirVariableAssignment,
|
expression: FirVariableAssignment,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter
|
reporter: DiagnosticReporter
|
||||||
) {
|
) {
|
||||||
if (expression.lValue is FirThisReference) {
|
val calleeReference = expression.calleeReference
|
||||||
|
|
||||||
|
if (expression.unwrapLValue() !is FirPropertyAccessExpression ||
|
||||||
|
(calleeReference?.isConflictingError() != true && calleeReference?.toResolvedVariableSymbol() == null)
|
||||||
|
) {
|
||||||
reporter.reportOn(expression.lValue.source, FirErrors.VARIABLE_EXPECTED, context)
|
reporter.reportOn(expression.lValue.source, FirErrors.VARIABLE_EXPECTED, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirReference.isConflictingError(): Boolean {
|
||||||
|
if (!isError()) return false
|
||||||
|
|
||||||
|
return when (val it = diagnostic) {
|
||||||
|
is ConeSimpleDiagnostic -> it.kind == DiagnosticKind.VariableExpected
|
||||||
|
is ConeUnresolvedNameError -> true
|
||||||
|
is ConeDiagnosticWithCandidates -> it.candidates.any { it.symbol is FirPropertySymbol }
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkValReassignment(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
private fun checkValReassignment(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val property = expression.lValue.toResolvedPropertySymbol() ?: return
|
val property = expression.calleeReference?.toResolvedPropertySymbol() ?: return
|
||||||
if (property.isVar) return
|
if (property.isVar) return
|
||||||
// Assignments of uninitialized `val`s must be checked via CFG, since the first one is OK.
|
// Assignments of uninitialized `val`s must be checked via CFG, since the first one is OK.
|
||||||
// See `FirPropertyInitializationAnalyzer` for locals and `FirMemberPropertiesChecker` for backing fields in initializers.
|
// See `FirPropertyInitializationAnalyzer` for locals and `FirMemberPropertiesChecker` for backing fields in initializers.
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ object FirReturnSyntaxAndLabelChecker : FirReturnExpressionChecker() {
|
|||||||
if (targetSymbol is FirAnonymousFunctionSymbol) {
|
if (targetSymbol is FirAnonymousFunctionSymbol) {
|
||||||
val label = targetSymbol.label
|
val label = targetSymbol.label
|
||||||
if (label?.source?.kind !is KtRealSourceElementKind) {
|
if (label?.source?.kind !is KtRealSourceElementKind) {
|
||||||
val functionCall = context.qualifiedAccessOrAnnotationCalls.asReversed().find {
|
val functionCall = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.asReversed().find {
|
||||||
it is FirFunctionCall &&
|
it is FirFunctionCall &&
|
||||||
(it.calleeReference.toResolvedFunctionSymbol())?.callableId ==
|
(it.calleeReference.toResolvedFunctionSymbol())?.callableId ==
|
||||||
FirSuspendCallChecker.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_CALLABLE_ID
|
FirSuspendCallChecker.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_CALLABLE_ID
|
||||||
|
|||||||
+2
-2
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.types.isUnit
|
|||||||
|
|
||||||
object FirStandaloneQualifierChecker : FirResolvedQualifierChecker() {
|
object FirStandaloneQualifierChecker : FirResolvedQualifierChecker() {
|
||||||
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val lastQualifiedAccess = context.qualifiedAccessOrAnnotationCalls.lastOrNull() as? FirQualifiedAccess
|
val lastQualifiedAccess = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.lastOrNull() as? FirQualifiedAccessExpression
|
||||||
// Note: qualifier isn't standalone when it's in receiver (SomeClass.foo) or getClass (SomeClass::class) position
|
// Note: qualifier isn't standalone when it's in receiver (SomeClass.foo) or getClass (SomeClass::class) position
|
||||||
if (lastQualifiedAccess?.explicitReceiver === expression || lastQualifiedAccess?.dispatchReceiver === expression) return
|
if (lastQualifiedAccess?.explicitReceiver === expression || lastQualifiedAccess?.dispatchReceiver === expression) return
|
||||||
val lastGetClass = context.getClassCalls.lastOrNull()
|
val lastGetClass = context.getClassCalls.lastOrNull()
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ object FirTypeParameterInQualifiedAccessChecker : FirQualifiedAccessExpressionCh
|
|||||||
// Make sure the current expression is not the receiver of a qualified access expression.
|
// Make sure the current expression is not the receiver of a qualified access expression.
|
||||||
// E.g., for `T::toString`, which is a callable reference (a subtype of qualified access), type parameter T is checked once as an
|
// E.g., for `T::toString`, which is a callable reference (a subtype of qualified access), type parameter T is checked once as an
|
||||||
// explicit receiver. When we visit `T` (as a qualified access expression), we should not regard it as an expression here.
|
// explicit receiver. When we visit `T` (as a qualified access expression), we should not regard it as an expression here.
|
||||||
val secondLast = context.qualifiedAccessOrAnnotationCalls.elementAtOrNull(context.qualifiedAccessOrAnnotationCalls.size - 2)
|
val secondLast = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.elementAtOrNull(context.qualifiedAccessOrAssignmentsOrAnnotationCalls.size - 2)
|
||||||
if (secondLast is FirQualifiedAccessExpression && secondLast.explicitReceiver == expression) return
|
if (secondLast is FirQualifiedAccessExpression && secondLast.explicitReceiver == expression) return
|
||||||
|
|
||||||
val diagnostic = expression.typeRef.coneTypeParameterInQualifiedAccess ?: return
|
val diagnostic = expression.typeRef.coneTypeParameterInQualifiedAccess ?: return
|
||||||
|
|||||||
+3
-3
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.expressions.*
|
|||||||
object FirUnsupportedArrayLiteralChecker : FirArrayOfCallChecker() {
|
object FirUnsupportedArrayLiteralChecker : FirArrayOfCallChecker() {
|
||||||
override fun check(expression: FirArrayOfCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirArrayOfCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
if (!isInsideAnnotationCall(expression, context) &&
|
if (!isInsideAnnotationCall(expression, context) &&
|
||||||
(context.qualifiedAccessOrAnnotationCalls.isNotEmpty() || !isInsideAnnotationClass(context))
|
(context.qualifiedAccessOrAssignmentsOrAnnotationCalls.isNotEmpty() || !isInsideAnnotationClass(context))
|
||||||
) {
|
) {
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
expression.source,
|
expression.source,
|
||||||
@@ -32,7 +32,7 @@ object FirUnsupportedArrayLiteralChecker : FirArrayOfCallChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isInsideAnnotationCall(expression: FirArrayOfCall, context: CheckerContext): Boolean {
|
private fun isInsideAnnotationCall(expression: FirArrayOfCall, context: CheckerContext): Boolean {
|
||||||
context.qualifiedAccessOrAnnotationCalls.lastOrNull()?.let {
|
context.qualifiedAccessOrAssignmentsOrAnnotationCalls.lastOrNull()?.let {
|
||||||
val arguments = when (it) {
|
val arguments = when (it) {
|
||||||
is FirFunctionCall ->
|
is FirFunctionCall ->
|
||||||
if (it.typeRef.toRegularClassSymbol(context.session)?.classKind == ClassKind.ANNOTATION_CLASS) {
|
if (it.typeRef.toRegularClassSymbol(context.session)?.classKind == ClassKind.ANNOTATION_CLASS) {
|
||||||
@@ -87,4 +87,4 @@ object FirUnsupportedArrayLiteralChecker : FirArrayOfCallChecker() {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.diagnostics.reportOn
|
|||||||
import org.jetbrains.kotlin.fir.dispatchReceiverClassTypeOrNull
|
import org.jetbrains.kotlin.fir.dispatchReceiverClassTypeOrNull
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.calleeReference
|
||||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
@@ -32,7 +33,7 @@ import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
|||||||
|
|
||||||
object CanBeReplacedWithOperatorAssignmentChecker : FirVariableAssignmentChecker() {
|
object CanBeReplacedWithOperatorAssignmentChecker : FirVariableAssignmentChecker() {
|
||||||
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val lValue = expression.lValue
|
val lValue = expression.calleeReference
|
||||||
if (lValue !is FirResolvedNamedReference) return
|
if (lValue !is FirResolvedNamedReference) return
|
||||||
if (expression.source?.kind is KtFakeSourceElementKind) return
|
if (expression.source?.kind is KtFakeSourceElementKind) return
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
|
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.cfa.util.PropertyInitializationInfoData
|
import org.jetbrains.kotlin.fir.analysis.cfa.util.PropertyInitializationInfoData
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.calleeReference
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
@@ -48,7 +49,7 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() {
|
|||||||
override fun visitNode(node: CFGNode<*>) {}
|
override fun visitNode(node: CFGNode<*>) {}
|
||||||
|
|
||||||
override fun visitVariableAssignmentNode(node: VariableAssignmentNode) {
|
override fun visitVariableAssignmentNode(node: VariableAssignmentNode) {
|
||||||
val symbol = node.fir.calleeReference.toResolvedPropertySymbol() ?: return
|
val symbol = node.fir.calleeReference?.toResolvedPropertySymbol() ?: return
|
||||||
if (symbol.isVar && symbol.source?.kind !is KtFakeSourceElementKind && symbol in data.properties &&
|
if (symbol.isVar && symbol.source?.kind !is KtFakeSourceElementKind && symbol in data.properties &&
|
||||||
(!symbol.requiresInitialization || data.getValue(node).values.any { it[symbol]?.canBeRevisited() == true })
|
(!symbol.requiresInitialization || data.getValue(node).values.any { it[symbol]?.canBeRevisited() == true })
|
||||||
) {
|
) {
|
||||||
|
|||||||
+5
-5
@@ -44,7 +44,7 @@ object UnusedChecker : AbstractFirPropertyInitializationChecker() {
|
|||||||
override fun visitNode(node: CFGNode<*>) {}
|
override fun visitNode(node: CFGNode<*>) {}
|
||||||
|
|
||||||
override fun visitVariableAssignmentNode(node: VariableAssignmentNode) {
|
override fun visitVariableAssignmentNode(node: VariableAssignmentNode) {
|
||||||
val variableSymbol = node.fir.calleeReference.toResolvedPropertySymbol() ?: return
|
val variableSymbol = node.fir.calleeReference?.toResolvedPropertySymbol() ?: return
|
||||||
val dataPerNode = data[node] ?: return
|
val dataPerNode = data[node] ?: return
|
||||||
for (dataPerLabel in dataPerNode.values) {
|
for (dataPerLabel in dataPerNode.values) {
|
||||||
val data = dataPerLabel[variableSymbol] ?: continue
|
val data = dataPerLabel[variableSymbol] ?: continue
|
||||||
@@ -210,7 +210,7 @@ object UnusedChecker : AbstractFirPropertyInitializationChecker() {
|
|||||||
data: PathAwareVariableStatusInfo
|
data: PathAwareVariableStatusInfo
|
||||||
): PathAwareVariableStatusInfo {
|
): PathAwareVariableStatusInfo {
|
||||||
val dataForNode = visitNode(node, data)
|
val dataForNode = visitNode(node, data)
|
||||||
val symbol = node.fir.lValue.toResolvedPropertySymbol() ?: return dataForNode
|
val symbol = node.fir.calleeReference?.toResolvedPropertySymbol() ?: return dataForNode
|
||||||
return update(dataForNode, symbol) update@{ prev ->
|
return update(dataForNode, symbol) update@{ prev ->
|
||||||
val toPut = when {
|
val toPut = when {
|
||||||
symbol !in localProperties -> {
|
symbol !in localProperties -> {
|
||||||
@@ -247,7 +247,7 @@ object UnusedChecker : AbstractFirPropertyInitializationChecker() {
|
|||||||
annotation: FirAnnotation,
|
annotation: FirAnnotation,
|
||||||
): PathAwareVariableStatusInfo {
|
): PathAwareVariableStatusInfo {
|
||||||
return if (annotation is FirAnnotationCall) {
|
return if (annotation is FirAnnotationCall) {
|
||||||
val qualifiedAccesses = annotation.argumentList.arguments.mapNotNull { it as? FirQualifiedAccess }.toTypedArray()
|
val qualifiedAccesses = annotation.argumentList.arguments.mapNotNull { it as? FirQualifiedAccessExpression }.toTypedArray()
|
||||||
visitQualifiedAccesses(dataForNode, *qualifiedAccesses)
|
visitQualifiedAccesses(dataForNode, *qualifiedAccesses)
|
||||||
} else {
|
} else {
|
||||||
dataForNode
|
dataForNode
|
||||||
@@ -256,9 +256,9 @@ object UnusedChecker : AbstractFirPropertyInitializationChecker() {
|
|||||||
|
|
||||||
private fun visitQualifiedAccesses(
|
private fun visitQualifiedAccesses(
|
||||||
dataForNode: PathAwareVariableStatusInfo,
|
dataForNode: PathAwareVariableStatusInfo,
|
||||||
vararg qualifiedAccesses: FirQualifiedAccess,
|
vararg qualifiedAccesses: FirQualifiedAccessExpression,
|
||||||
): PathAwareVariableStatusInfo {
|
): PathAwareVariableStatusInfo {
|
||||||
fun retrieveSymbol(qualifiedAccess: FirQualifiedAccess): FirPropertySymbol? {
|
fun retrieveSymbol(qualifiedAccess: FirQualifiedAccessExpression): FirPropertySymbol? {
|
||||||
return qualifiedAccess.calleeReference.toResolvedPropertySymbol()?.takeIf { it in localProperties }
|
return qualifiedAccess.calleeReference.toResolvedPropertySymbol()?.takeIf { it in localProperties }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ object FirOptInUsageTypeRefChecker : FirTypeRefChecker() {
|
|||||||
val symbol = coneType.lookupTag.toSymbol(context.session) ?: return
|
val symbol = coneType.lookupTag.toSymbol(context.session) ?: return
|
||||||
symbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
symbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||||
val classId = symbol.classId
|
val classId = symbol.classId
|
||||||
val lastAnnotationCall = context.qualifiedAccessOrAnnotationCalls.lastOrNull() as? FirAnnotation
|
val lastAnnotationCall = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.lastOrNull() as? FirAnnotation
|
||||||
if (lastAnnotationCall == null || lastAnnotationCall.annotationTypeRef !== typeRef) {
|
if (lastAnnotationCall == null || lastAnnotationCall.annotationTypeRef !== typeRef) {
|
||||||
if (classId == OptInNames.REQUIRES_OPT_IN_CLASS_ID || classId == OptInNames.OPT_IN_CLASS_ID) {
|
if (classId == OptInNames.REQUIRES_OPT_IN_CLASS_ID || classId == OptInNames.OPT_IN_CLASS_ID) {
|
||||||
reporter.reportOn(source, OPT_IN_CAN_ONLY_BE_USED_AS_ANNOTATION, context)
|
reporter.reportOn(source, OPT_IN_CAN_ONLY_BE_USED_AS_ANNOTATION, context)
|
||||||
|
|||||||
+5
-1
@@ -36,9 +36,13 @@ abstract class AbstractDiagnosticCollectorVisitor(
|
|||||||
|
|
||||||
override fun visitElement(element: FirElement, data: Nothing?) {
|
override fun visitElement(element: FirElement, data: Nothing?) {
|
||||||
if (element is FirAnnotationContainer) {
|
if (element is FirAnnotationContainer) {
|
||||||
visitAnnotationContainer(element, data)
|
withAnnotationContainer(element) {
|
||||||
|
checkElement(element)
|
||||||
|
visitNestedElements(element)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
checkElement(element)
|
checkElement(element)
|
||||||
visitNestedElements(element)
|
visitNestedElements(element)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-11
@@ -23,10 +23,7 @@ import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
|||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
|
||||||
|
|
||||||
class ErrorNodeDiagnosticCollectorComponent(
|
class ErrorNodeDiagnosticCollectorComponent(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
@@ -63,13 +60,9 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
|
|
||||||
private fun processErrorReference(reference: FirNamedReference, diagnostic: ConeDiagnostic, context: CheckerContext) {
|
private fun processErrorReference(reference: FirNamedReference, diagnostic: ConeDiagnostic, context: CheckerContext) {
|
||||||
val source = reference.source ?: return
|
val source = reference.source ?: return
|
||||||
val qualifiedAccessOrAnnotationCall = context.qualifiedAccessOrAnnotationCalls.lastOrNull()?.takeIf {
|
val qualifiedAccessOrAnnotationCall = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.lastOrNull()?.takeIf {
|
||||||
// Use the source of the enclosing FirQualifiedAccess if it is exactly the call to the erroneous callee.
|
// Use the source of the enclosing FirQualifiedAccess if it is exactly the call to the erroneous callee.
|
||||||
when (it) {
|
it.calleeReference == reference
|
||||||
is FirQualifiedAccess -> it.calleeReference == reference
|
|
||||||
is FirAnnotationCall -> it.calleeReference == reference
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Don't report duplicated unresolved reference on annotation entry (already reported on its type)
|
// Don't report duplicated unresolved reference on annotation entry (already reported on its type)
|
||||||
if (source.elementType == KtNodeTypes.ANNOTATION_ENTRY && diagnostic is ConeUnresolvedNameError) return
|
if (source.elementType == KtNodeTypes.ANNOTATION_ENTRY && diagnostic is ConeUnresolvedNameError) return
|
||||||
@@ -79,7 +72,7 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
) return
|
) return
|
||||||
|
|
||||||
// If the receiver cannot be resolved, we skip reporting any further problems for this call.
|
// If the receiver cannot be resolved, we skip reporting any further problems for this call.
|
||||||
if (qualifiedAccessOrAnnotationCall is FirQualifiedAccess) {
|
if (qualifiedAccessOrAnnotationCall is FirQualifiedAccessExpression) {
|
||||||
if (qualifiedAccessOrAnnotationCall.dispatchReceiver.cannotBeResolved() ||
|
if (qualifiedAccessOrAnnotationCall.dispatchReceiver.cannotBeResolved() ||
|
||||||
qualifiedAccessOrAnnotationCall.extensionReceiver.cannotBeResolved() ||
|
qualifiedAccessOrAnnotationCall.extensionReceiver.cannotBeResolved() ||
|
||||||
qualifiedAccessOrAnnotationCall.explicitReceiver.cannotBeResolved()
|
qualifiedAccessOrAnnotationCall.explicitReceiver.cannotBeResolved()
|
||||||
|
|||||||
-4
@@ -91,10 +91,6 @@ private fun ConeDiagnostic.toKtDiagnostic(
|
|||||||
|
|
||||||
is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.createOn(source, this.candidateSymbols)
|
is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.createOn(source, this.candidateSymbols)
|
||||||
is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.createOn(source)
|
is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.createOn(source)
|
||||||
is ConeValReassignmentError -> when (val symbol = this.variable) {
|
|
||||||
is FirBackingFieldSymbol -> FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD.errorFactory.createOn(source, symbol)
|
|
||||||
else -> FirErrors.VAL_REASSIGNMENT.createOn(source, symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.createOn(this.source ?: source)
|
is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.createOn(this.source ?: source)
|
||||||
is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.createOn(source, this.name.asString())
|
is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.createOn(source, this.name.asString())
|
||||||
|
|||||||
@@ -727,7 +727,6 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FlowContent.generate(variableAssignment: FirVariableAssignment) {
|
private fun FlowContent.generate(variableAssignment: FirVariableAssignment) {
|
||||||
generateReceiver(variableAssignment)
|
|
||||||
generate(variableAssignment.lValue)
|
generate(variableAssignment.lValue)
|
||||||
+" = "
|
+" = "
|
||||||
generate(variableAssignment.rValue)
|
generate(variableAssignment.rValue)
|
||||||
@@ -1324,7 +1323,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FlowContent.generateReceiver(access: FirQualifiedAccess) {
|
private fun FlowContent.generateReceiver(access: FirQualifiedAccessExpression) {
|
||||||
val explicitReceiver = access.explicitReceiver
|
val explicitReceiver = access.explicitReceiver
|
||||||
if (explicitReceiver != null) {
|
if (explicitReceiver != null) {
|
||||||
generate(explicitReceiver)
|
generate(explicitReceiver)
|
||||||
@@ -1608,14 +1607,10 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
|||||||
+"?."
|
+"?."
|
||||||
|
|
||||||
val selector = safeCallExpression.selector
|
val selector = safeCallExpression.selector
|
||||||
if (selector is FirQualifiedAccess && selector.explicitReceiver == safeCallExpression.checkedSubjectRef.value) {
|
if (selector is FirQualifiedAccessExpression && selector.explicitReceiver == safeCallExpression.checkedSubjectRef.value) {
|
||||||
when (selector) {
|
return when (selector) {
|
||||||
is FirFunctionCall -> {
|
is FirFunctionCall -> generate(selector, skipReceiver = true)
|
||||||
return generate(selector, skipReceiver = true)
|
else -> generate(selector, skipReceiver = true)
|
||||||
}
|
|
||||||
is FirQualifiedAccessExpression -> {
|
|
||||||
return generate(selector, skipReceiver = true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,14 @@ internal fun <T : IrElement> KtSourceElement?.convertWithOffsets(
|
|||||||
return f(startOffset, endOffset)
|
return f(startOffset, endOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun <T : IrElement> FirQualifiedAccess.convertWithOffsets(
|
internal fun <T : IrElement> FirQualifiedAccessExpression.convertWithOffsets(
|
||||||
|
f: (startOffset: Int, endOffset: Int) -> T
|
||||||
|
): T {
|
||||||
|
return convertWithOffsets(this.calleeReference, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun <T : IrElement> FirStatement.convertWithOffsets(
|
||||||
|
calleeReference: FirReference,
|
||||||
f: (startOffset: Int, endOffset: Int) -> T
|
f: (startOffset: Int, endOffset: Int) -> T
|
||||||
): T {
|
): T {
|
||||||
val psi = calleeReference.psi
|
val psi = calleeReference.psi
|
||||||
@@ -718,7 +725,7 @@ fun FirDeclaration?.computeIrOrigin(predefinedOrigin: IrDeclarationOrigin? = nul
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun FirVariableAssignment.getIrAssignmentOrigin(): IrStatementOrigin {
|
fun FirVariableAssignment.getIrAssignmentOrigin(): IrStatementOrigin {
|
||||||
val calleeReferenceSymbol = calleeReference.toResolvedCallableSymbol() ?: return IrStatementOrigin.EQ
|
val calleeReferenceSymbol = calleeReference?.toResolvedCallableSymbol() ?: return IrStatementOrigin.EQ
|
||||||
val rValue = rValue
|
val rValue = rValue
|
||||||
if (rValue is FirFunctionCall && calleeReferenceSymbol.callableId.isLocal) {
|
if (rValue is FirFunctionCall && calleeReferenceSymbol.callableId.isLocal) {
|
||||||
val callableId = rValue.calleeReference.toResolvedCallableSymbol()?.callableId
|
val callableId = rValue.calleeReference.toResolvedCallableSymbol()?.callableId
|
||||||
@@ -736,9 +743,8 @@ fun FirVariableAssignment.getIrAssignmentOrigin(): IrStatementOrigin {
|
|||||||
IrStatementOrigin.POSTFIX_DECR
|
IrStatementOrigin.POSTFIX_DECR
|
||||||
}
|
}
|
||||||
|
|
||||||
if (calleeReference.source?.kind is KtFakeSourceElementKind &&
|
val kind = rValue.source?.kind
|
||||||
calleeReferenceSymbol == rValue.explicitReceiver?.toResolvedCallableSymbol()
|
if (kind == KtFakeSourceElementKind.DesugaredIncrementOrDecrement || kind == KtFakeSourceElementKind.DesugaredCompoundAssignment) {
|
||||||
) {
|
|
||||||
if (callableName == OperatorNameConventions.PLUS) {
|
if (callableName == OperatorNameConventions.PLUS) {
|
||||||
return IrStatementOrigin.PLUSEQ
|
return IrStatementOrigin.PLUSEQ
|
||||||
} else if (callableName == OperatorNameConventions.MINUS) {
|
} else if (callableName == OperatorNameConventions.MINUS) {
|
||||||
|
|||||||
+1
-1
@@ -913,7 +913,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
val setter = property.setter
|
val setter = property.setter
|
||||||
if (delegate != null || property.hasBackingField) {
|
if (delegate != null || property.hasBackingField) {
|
||||||
backingField = if (delegate != null) {
|
backingField = if (delegate != null) {
|
||||||
((delegate as? FirQualifiedAccess)?.calleeReference?.toResolvedBaseSymbol()?.fir as? FirTypeParameterRefsOwner)?.let {
|
((delegate as? FirQualifiedAccessExpression)?.calleeReference?.toResolvedBaseSymbol()?.fir as? FirTypeParameterRefsOwner)?.let {
|
||||||
classifierStorage.preCacheTypeParameters(it, symbol)
|
classifierStorage.preCacheTypeParameters(it, symbol)
|
||||||
}
|
}
|
||||||
createBackingField(
|
createBackingField(
|
||||||
|
|||||||
+2
-2
@@ -274,10 +274,10 @@ class Fir2IrImplicitCastInserter(
|
|||||||
internal fun implicitCastFromDispatchReceiver(
|
internal fun implicitCastFromDispatchReceiver(
|
||||||
original: IrExpression,
|
original: IrExpression,
|
||||||
originalTypeRef: FirTypeRef,
|
originalTypeRef: FirTypeRef,
|
||||||
calleeReference: FirReference,
|
calleeReference: FirReference?,
|
||||||
conversionTypeContext: ConversionTypeContext,
|
conversionTypeContext: ConversionTypeContext,
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
val referencedDeclaration = calleeReference.toResolvedCallableSymbol()?.unwrapCallRepresentative()?.fir
|
val referencedDeclaration = calleeReference?.toResolvedCallableSymbol()?.unwrapCallRepresentative()?.fir
|
||||||
|
|
||||||
val dispatchReceiverType =
|
val dispatchReceiverType =
|
||||||
referencedDeclaration?.dispatchReceiverType as? ConeClassLikeType
|
referencedDeclaration?.dispatchReceiverType as? ConeClassLikeType
|
||||||
|
|||||||
@@ -704,7 +704,7 @@ class Fir2IrVisitor(
|
|||||||
|
|
||||||
internal fun convertToIrReceiverExpression(
|
internal fun convertToIrReceiverExpression(
|
||||||
expression: FirExpression?,
|
expression: FirExpression?,
|
||||||
calleeReference: FirReference,
|
calleeReference: FirReference?,
|
||||||
callableReferenceAccess: FirCallableReferenceAccess? = null
|
callableReferenceAccess: FirCallableReferenceAccess? = null
|
||||||
): IrExpression? {
|
): IrExpression? {
|
||||||
return when (expression) {
|
return when (expression) {
|
||||||
@@ -779,7 +779,7 @@ class Fir2IrVisitor(
|
|||||||
val incrementStatement = this[index + 1]
|
val incrementStatement = this[index + 1]
|
||||||
if (incrementStatement !is FirVariableAssignment) return null
|
if (incrementStatement !is FirVariableAssignment) return null
|
||||||
|
|
||||||
if (incrementStatement.lValue.toResolvedCallableSymbol() != variable) return null
|
if (incrementStatement.calleeReference?.toResolvedCallableSymbol() != variable) return null
|
||||||
|
|
||||||
val origin = incrementStatement.getIrAssignmentOrigin()
|
val origin = incrementStatement.getIrAssignmentOrigin()
|
||||||
return if (origin == IrStatementOrigin.EQ) null else origin
|
return if (origin == IrStatementOrigin.EQ) null else origin
|
||||||
|
|||||||
+4
-1
@@ -180,7 +180,10 @@ internal class AdapterGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirQualifiedAccess.findBoundReceiver(explicitReceiverExpression: IrExpression?, isDispatch: Boolean): IrExpression? {
|
private fun FirCallableReferenceAccess.findBoundReceiver(
|
||||||
|
explicitReceiverExpression: IrExpression?,
|
||||||
|
isDispatch: Boolean
|
||||||
|
): IrExpression? {
|
||||||
val firReceiver = if (isDispatch) dispatchReceiver else extensionReceiver
|
val firReceiver = if (isDispatch) dispatchReceiver else extensionReceiver
|
||||||
if (firReceiver is FirNoReceiverExpression) {
|
if (firReceiver is FirNoReceiverExpression) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
+20
-17
@@ -213,7 +213,7 @@ class CallAndReferenceGenerator(
|
|||||||
return newType.toTypeProjection(typeProjection.kind)
|
return newType.toTypeProjection(typeProjection.kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirQualifiedAccess.tryConvertToSamConstructorCall(type: IrType): IrTypeOperatorCall? {
|
private fun FirQualifiedAccessExpression.tryConvertToSamConstructorCall(type: IrType): IrTypeOperatorCall? {
|
||||||
val calleeReference = calleeReference as? FirResolvedNamedReference ?: return null
|
val calleeReference = calleeReference as? FirResolvedNamedReference ?: return null
|
||||||
val fir = calleeReference.resolvedSymbol.fir
|
val fir = calleeReference.resolvedSymbol.fir
|
||||||
if (this is FirFunctionCall && fir is FirSimpleFunction && fir.origin == FirDeclarationOrigin.SamConstructor) {
|
if (this is FirFunctionCall && fir is FirSimpleFunction && fir.origin == FirDeclarationOrigin.SamConstructor) {
|
||||||
@@ -227,7 +227,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FirExpression.superQualifierSymbol(): IrClassSymbol? {
|
private fun FirExpression.superQualifierSymbol(): IrClassSymbol? {
|
||||||
if (this !is FirQualifiedAccess) {
|
if (this !is FirQualifiedAccessExpression) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
val dispatchReceiverReference = calleeReference
|
val dispatchReceiverReference = calleeReference
|
||||||
@@ -264,7 +264,7 @@ class CallAndReferenceGenerator(
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
private val FirQualifiedAccess.dynamicOperator
|
private val FirQualifiedAccessExpression.dynamicOperator
|
||||||
get() = when (calleeReference.source?.kind) {
|
get() = when (calleeReference.source?.kind) {
|
||||||
is KtFakeSourceElementKind.ArrayAccessNameReference -> when (calleeReference.resolved?.name) {
|
is KtFakeSourceElementKind.ArrayAccessNameReference -> when (calleeReference.resolved?.name) {
|
||||||
OperatorNameConventions.SET -> IrDynamicOperator.EQ
|
OperatorNameConventions.SET -> IrDynamicOperator.EQ
|
||||||
@@ -288,7 +288,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun convertToIrCallForDynamic(
|
private fun convertToIrCallForDynamic(
|
||||||
qualifiedAccess: FirQualifiedAccess,
|
qualifiedAccess: FirQualifiedAccessExpression,
|
||||||
explicitReceiverExpression: IrExpression,
|
explicitReceiverExpression: IrExpression,
|
||||||
type: IrType,
|
type: IrType,
|
||||||
calleeReference: FirReference,
|
calleeReference: FirReference,
|
||||||
@@ -333,7 +333,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun convertToIrCall(
|
fun convertToIrCall(
|
||||||
qualifiedAccess: FirQualifiedAccess,
|
qualifiedAccess: FirQualifiedAccessExpression,
|
||||||
typeRef: FirTypeRef,
|
typeRef: FirTypeRef,
|
||||||
explicitReceiverExpression: IrExpression?,
|
explicitReceiverExpression: IrExpression?,
|
||||||
annotationMode: Boolean = false,
|
annotationMode: Boolean = false,
|
||||||
@@ -501,13 +501,15 @@ class CallAndReferenceGenerator(
|
|||||||
|
|
||||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||||
}
|
}
|
||||||
}.applyTypeArguments(variableAssignment).applyReceivers(variableAssignment, convertedExplicitReceiver)
|
}.apply {
|
||||||
|
variableAssignment.unwrapLValue()?.let { applyReceivers(it, convertedExplicitReceiver) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertToIrSetCall(variableAssignment: FirVariableAssignment, explicitReceiverExpression: IrExpression?): IrExpression {
|
fun convertToIrSetCall(variableAssignment: FirVariableAssignment, explicitReceiverExpression: IrExpression?): IrExpression {
|
||||||
try {
|
try {
|
||||||
val type = irBuiltIns.unitType
|
val type = irBuiltIns.unitType
|
||||||
val calleeReference = variableAssignment.calleeReference
|
val calleeReference = variableAssignment.calleeReference ?: error("Reference not resolvable")
|
||||||
val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue)
|
val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue)
|
||||||
|
|
||||||
val firSymbol = calleeReference.toResolvedBaseSymbol()
|
val firSymbol = calleeReference.toResolvedBaseSymbol()
|
||||||
@@ -532,7 +534,8 @@ class CallAndReferenceGenerator(
|
|||||||
)
|
)
|
||||||
val origin = variableAssignment.getIrAssignmentOrigin()
|
val origin = variableAssignment.getIrAssignmentOrigin()
|
||||||
|
|
||||||
return variableAssignment.convertWithOffsets { startOffset, endOffset ->
|
val lValue = variableAssignment.unwrapLValue() ?: error("Assignment lValue unwrapped to null")
|
||||||
|
return variableAssignment.convertWithOffsets(calleeReference) { startOffset, endOffset ->
|
||||||
when (symbol) {
|
when (symbol) {
|
||||||
is IrFieldSymbol -> IrSetFieldImpl(startOffset, endOffset, symbol, type, origin).apply {
|
is IrFieldSymbol -> IrSetFieldImpl(startOffset, endOffset, symbol, type, origin).apply {
|
||||||
value = assignedValue
|
value = assignedValue
|
||||||
@@ -548,7 +551,7 @@ class CallAndReferenceGenerator(
|
|||||||
origin = origin,
|
origin = origin,
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
||||||
).apply {
|
).apply {
|
||||||
putContextReceiverArguments(variableAssignment)
|
putContextReceiverArguments(lValue)
|
||||||
putValueArgument(0, assignedValue)
|
putValueArgument(0, assignedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,7 +571,7 @@ class CallAndReferenceGenerator(
|
|||||||
origin = origin,
|
origin = origin,
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
||||||
).apply {
|
).apply {
|
||||||
putValueArgument(putContextReceiverArguments(variableAssignment), assignedValue)
|
putValueArgument(putContextReceiverArguments(lValue), assignedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
backingField != null -> IrSetFieldImpl(
|
backingField != null -> IrSetFieldImpl(
|
||||||
@@ -600,7 +603,7 @@ class CallAndReferenceGenerator(
|
|||||||
|
|
||||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||||
}
|
}
|
||||||
}.applyTypeArguments(variableAssignment).applyReceivers(variableAssignment, explicitReceiverExpression)
|
}.applyTypeArguments(lValue).applyReceivers(lValue, explicitReceiverExpression)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
throw IllegalStateException(
|
throw IllegalStateException(
|
||||||
"Error while translating ${variableAssignment.render()} " +
|
"Error while translating ${variableAssignment.render()} " +
|
||||||
@@ -957,7 +960,7 @@ class CallAndReferenceGenerator(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrExpression.applyTypeArguments(access: FirQualifiedAccess): IrExpression {
|
internal fun IrExpression.applyTypeArguments(access: FirQualifiedAccessExpression): IrExpression {
|
||||||
if (this !is IrMemberAccessExpression<*>) return this
|
if (this !is IrMemberAccessExpression<*>) return this
|
||||||
val argumentsCount = access.typeArguments.size
|
val argumentsCount = access.typeArguments.size
|
||||||
if (argumentsCount <= typeArgumentsCount) {
|
if (argumentsCount <= typeArgumentsCount) {
|
||||||
@@ -986,16 +989,16 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirQualifiedAccess.findTypeParameter(index: Int): FirTypeParameter? =
|
private fun FirQualifiedAccessExpression.findTypeParameter(index: Int): FirTypeParameter? =
|
||||||
((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol?.fir as? FirTypeParametersOwner)?.typeParameters?.get(index)
|
((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol?.fir as? FirTypeParametersOwner)?.typeParameters?.get(index)
|
||||||
|
|
||||||
private fun FirQualifiedAccess.findIrDispatchReceiver(explicitReceiverExpression: IrExpression?): IrExpression? =
|
private fun FirQualifiedAccessExpression.findIrDispatchReceiver(explicitReceiverExpression: IrExpression?): IrExpression? =
|
||||||
findIrReceiver(explicitReceiverExpression, isDispatch = true)
|
findIrReceiver(explicitReceiverExpression, isDispatch = true)
|
||||||
|
|
||||||
private fun FirQualifiedAccess.findIrExtensionReceiver(explicitReceiverExpression: IrExpression?): IrExpression? =
|
private fun FirQualifiedAccessExpression.findIrExtensionReceiver(explicitReceiverExpression: IrExpression?): IrExpression? =
|
||||||
findIrReceiver(explicitReceiverExpression, isDispatch = false)
|
findIrReceiver(explicitReceiverExpression, isDispatch = false)
|
||||||
|
|
||||||
internal fun FirQualifiedAccess.findIrReceiver(explicitReceiverExpression: IrExpression?, isDispatch: Boolean): IrExpression? {
|
internal fun FirQualifiedAccessExpression.findIrReceiver(explicitReceiverExpression: IrExpression?, isDispatch: Boolean): IrExpression? {
|
||||||
val firReceiver = if (isDispatch) dispatchReceiver else extensionReceiver
|
val firReceiver = if (isDispatch) dispatchReceiver else extensionReceiver
|
||||||
if (firReceiver == explicitReceiver) {
|
if (firReceiver == explicitReceiver) {
|
||||||
return explicitReceiverExpression
|
return explicitReceiverExpression
|
||||||
@@ -1011,7 +1014,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrExpression.applyReceivers(qualifiedAccess: FirQualifiedAccess, explicitReceiverExpression: IrExpression?): IrExpression {
|
private fun IrExpression.applyReceivers(qualifiedAccess: FirQualifiedAccessExpression, explicitReceiverExpression: IrExpression?): IrExpression {
|
||||||
when (this) {
|
when (this) {
|
||||||
is IrMemberAccessExpression<*> -> {
|
is IrMemberAccessExpression<*> -> {
|
||||||
val ownerFunction =
|
val ownerFunction =
|
||||||
|
|||||||
+4
-4
@@ -552,7 +552,7 @@ class ExpressionsConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result = firSelector
|
var result = firSelector
|
||||||
(firSelector as? FirQualifiedAccess)?.let {
|
(firSelector as? FirQualifiedAccessExpression)?.let {
|
||||||
if (isSafe) {
|
if (isSafe) {
|
||||||
@OptIn(FirImplementationDetail::class)
|
@OptIn(FirImplementationDetail::class)
|
||||||
it.replaceSource(dotQualifiedExpression.toFirSourceElement(KtFakeSourceElementKind.DesugaredSafeCallExpression))
|
it.replaceSource(dotQualifiedExpression.toFirSourceElement(KtFakeSourceElementKind.DesugaredSafeCallExpression))
|
||||||
@@ -562,7 +562,7 @@ class ExpressionsConverter(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
result = convertFirSelector(it, dotQualifiedExpression.toFirSourceElement(), firReceiver!!) as? FirExpression
|
result = convertFirSelector(it, dotQualifiedExpression.toFirSourceElement(), firReceiver!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiver = firReceiver
|
val receiver = firReceiver
|
||||||
@@ -663,7 +663,7 @@ class ExpressionsConverter(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val builder: FirQualifiedAccessBuilder = if (hasArguments) {
|
val builder: FirQualifiedAccessExpressionBuilder = if (hasArguments) {
|
||||||
val builder = if (isImplicitInvoke) FirImplicitInvokeCallBuilder() else FirFunctionCallBuilder()
|
val builder = if (isImplicitInvoke) FirImplicitInvokeCallBuilder() else FirFunctionCallBuilder()
|
||||||
builder.apply {
|
builder.apply {
|
||||||
this.source = source
|
this.source = source
|
||||||
@@ -682,7 +682,7 @@ class ExpressionsConverter(
|
|||||||
return builder.apply {
|
return builder.apply {
|
||||||
this.explicitReceiver = explicitReceiver
|
this.explicitReceiver = explicitReceiver
|
||||||
typeArguments += firTypeArguments
|
typeArguments += firTypeArguments
|
||||||
}.build() as FirExpression
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2545,7 +2545,7 @@ open class RawFirBuilder(
|
|||||||
val source = expression.toFirSourceElement()
|
val source = expression.toFirSourceElement()
|
||||||
val (calleeReference, explicitReceiver, isImplicitInvoke) = splitToCalleeAndReceiver(expression.calleeExpression, source)
|
val (calleeReference, explicitReceiver, isImplicitInvoke) = splitToCalleeAndReceiver(expression.calleeExpression, source)
|
||||||
|
|
||||||
val result: FirQualifiedAccessBuilder = if (expression.valueArgumentList == null && expression.lambdaArguments.isEmpty()) {
|
val result: FirQualifiedAccessExpressionBuilder = if (expression.valueArgumentList == null && expression.lambdaArguments.isEmpty()) {
|
||||||
FirPropertyAccessExpressionBuilder().apply {
|
FirPropertyAccessExpressionBuilder().apply {
|
||||||
this.source = source
|
this.source = source
|
||||||
this.calleeReference = calleeReference
|
this.calleeReference = calleeReference
|
||||||
@@ -2603,7 +2603,7 @@ open class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val firSelector = selector.toFirExpression("Incorrect selector expression")
|
val firSelector = selector.toFirExpression("Incorrect selector expression")
|
||||||
if (firSelector is FirQualifiedAccess) {
|
if (firSelector is FirQualifiedAccessExpression) {
|
||||||
if (expression is KtSafeQualifiedExpression) {
|
if (expression is KtSafeQualifiedExpression) {
|
||||||
@OptIn(FirImplementationDetail::class)
|
@OptIn(FirImplementationDetail::class)
|
||||||
firSelector.replaceSource(expression.toFirSourceElement(KtFakeSourceElementKind.DesugaredSafeCallExpression))
|
firSelector.replaceSource(expression.toFirSourceElement(KtFakeSourceElementKind.DesugaredSafeCallExpression))
|
||||||
|
|||||||
+4
-9
@@ -11,15 +11,10 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||||
import org.jetbrains.kotlin.fir.isCatchParameter
|
import org.jetbrains.kotlin.fir.isCatchParameter
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.isError
|
import org.jetbrains.kotlin.fir.references.isError
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.renderer.FirRenderer
|
import org.jetbrains.kotlin.fir.renderer.FirRenderer
|
||||||
@@ -84,15 +79,15 @@ class RawFirBuilderTotalKotlinTestCase : AbstractRawFirBuilderTestCase() {
|
|||||||
errorExpression.psi?.let { println(it) }
|
errorExpression.psi?.let { println(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitQualifiedAccess(qualifiedAccess: FirQualifiedAccess, data: FirElement) {
|
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: FirElement) {
|
||||||
val calleeReference = qualifiedAccess.calleeReference
|
val calleeReference = qualifiedAccessExpression.calleeReference
|
||||||
if (calleeReference.isError()) {
|
if (calleeReference.isError()) {
|
||||||
errorReferences++
|
errorReferences++
|
||||||
println((calleeReference as FirDiagnosticHolder).diagnostic.reason)
|
println((calleeReference as FirDiagnosticHolder).diagnostic.reason)
|
||||||
} else {
|
} else {
|
||||||
normalReferences++
|
normalReferences++
|
||||||
}
|
}
|
||||||
visitStatement(qualifiedAccess, data)
|
visitStatement(qualifiedAccessExpression, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitExpression(expression: FirExpression, data: FirElement) {
|
override fun visitExpression(expression: FirExpression, data: FirElement) {
|
||||||
|
|||||||
+28
-57
@@ -21,9 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
|||||||
import org.jetbrains.kotlin.fir.diagnostics.*
|
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.builder.*
|
import org.jetbrains.kotlin.fir.references.builder.*
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||||
@@ -558,9 +556,12 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
resultInitializer,
|
resultInitializer,
|
||||||
FirOperation.ASSIGN,
|
FirOperation.ASSIGN,
|
||||||
resultInitializer.annotations,
|
resultInitializer.annotations,
|
||||||
null,
|
null
|
||||||
convert
|
) {
|
||||||
)
|
// We want the DesugaredAssignmentValueReferenceExpression on the LHS to point to the same receiver instance
|
||||||
|
// as in the initializer, therefore don't create a new instance here if the argument is the receiver.
|
||||||
|
if (this == unwrappedReceiver) convertedReceiver else convert()
|
||||||
|
}
|
||||||
|
|
||||||
if (assignment is FirBlock) {
|
if (assignment is FirBlock) {
|
||||||
statements += assignment.statements
|
statements += assignment.statements
|
||||||
@@ -695,6 +696,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@OptIn(FirContractViolation::class)
|
||||||
private fun generateIncrementOrDecrementBlockForQualifiedAccess(
|
private fun generateIncrementOrDecrementBlockForQualifiedAccess(
|
||||||
wholeExpression: T,
|
wholeExpression: T,
|
||||||
operationReference: T?,
|
operationReference: T?,
|
||||||
@@ -708,7 +710,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
convert,
|
convert,
|
||||||
receiverForOperation.toFirSourceElement(),
|
receiverForOperation.toFirSourceElement(),
|
||||||
) { qualifiedFir ->
|
) { qualifiedFir ->
|
||||||
val receiverFir = (qualifiedFir as? FirQualifiedAccess)?.explicitReceiver ?: buildErrorExpression {
|
val receiverFir = (qualifiedFir as? FirQualifiedAccessExpression)?.explicitReceiver ?: buildErrorExpression {
|
||||||
source = receiverForOperation.toFirSourceElement()
|
source = receiverForOperation.toFirSourceElement()
|
||||||
diagnostic = ConeSimpleDiagnostic("Qualified expression without selector", DiagnosticKind.Syntax)
|
diagnostic = ConeSimpleDiagnostic("Qualified expression without selector", DiagnosticKind.Syntax)
|
||||||
}
|
}
|
||||||
@@ -724,7 +726,8 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
initializer = receiverFir,
|
initializer = receiverFir,
|
||||||
).also { statements += it }
|
).also { statements += it }
|
||||||
|
|
||||||
val firArgument = generateResolvedAccessExpression(argumentReceiverVariable.source, argumentReceiverVariable).let { receiver ->
|
val receiverSource = receiverFir.source?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement)
|
||||||
|
val firArgument = generateResolvedAccessExpression(receiverSource, argumentReceiverVariable).let { receiver ->
|
||||||
qualifiedFir.also { if (it is FirQualifiedAccessExpression) it.replaceExplicitReceiver(receiver) }
|
qualifiedFir.also { if (it is FirQualifiedAccessExpression) it.replaceExplicitReceiver(receiver) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -735,16 +738,15 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
if (firArgument !is FirQualifiedAccessExpression) return@putIncrementOrDecrementStatements
|
if (firArgument !is FirQualifiedAccessExpression) return@putIncrementOrDecrementStatements
|
||||||
statements += buildVariableAssignment {
|
statements += buildVariableAssignment {
|
||||||
source = desugaredSource
|
source = desugaredSource
|
||||||
|
lValue = buildDesugaredAssignmentValueReferenceExpression {
|
||||||
|
expressionRef = FirExpressionRef<FirExpression>().apply { bind(firArgument) }
|
||||||
|
source = firArgument.source?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement)
|
||||||
|
}
|
||||||
rValue = if (prefix) {
|
rValue = if (prefix) {
|
||||||
generateResolvedAccessExpression(source, resultVar)
|
generateResolvedAccessExpression(source, resultVar)
|
||||||
} else {
|
} else {
|
||||||
resultInitializer
|
resultInitializer
|
||||||
}
|
}
|
||||||
explicitReceiver = generateResolvedAccessExpression(argumentReceiverVariable.source, argumentReceiverVariable)
|
|
||||||
calleeReference = buildSimpleNamedReference {
|
|
||||||
source = firArgument.calleeReference.source
|
|
||||||
name = (firArgument.calleeReference as FirSimpleNamedReference).name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -891,46 +893,8 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirQualifiedAccessBuilder.initializeLValue(
|
|
||||||
left: T?,
|
|
||||||
convertQualified: T.() -> FirQualifiedAccess?
|
|
||||||
): FirReference {
|
|
||||||
val tokenType = left?.elementType
|
|
||||||
if (left != null) {
|
|
||||||
when (tokenType) {
|
|
||||||
REFERENCE_EXPRESSION -> {
|
|
||||||
return buildSimpleNamedReference {
|
|
||||||
source = left.toFirSourceElement()
|
|
||||||
name = left.getReferencedNameAsName()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
THIS_EXPRESSION -> {
|
|
||||||
return buildExplicitThisReference {
|
|
||||||
source = left.toFirSourceElement()
|
|
||||||
labelName = left.getLabelName()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DOT_QUALIFIED_EXPRESSION, SAFE_ACCESS_EXPRESSION -> {
|
|
||||||
val firMemberAccess = left.convertQualified()
|
|
||||||
return if (firMemberAccess != null) {
|
|
||||||
explicitReceiver = firMemberAccess.explicitReceiver
|
|
||||||
firMemberAccess.calleeReference
|
|
||||||
} else {
|
|
||||||
buildErrorNamedReference {
|
|
||||||
source = left.toFirSourceElement()
|
|
||||||
diagnostic = ConeSimpleDiagnostic("Unsupported qualified LValue: ${left.asText}", DiagnosticKind.Syntax)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buildErrorNamedReference {
|
|
||||||
source = left?.toFirSourceElement()
|
|
||||||
diagnostic = ConeSimpleDiagnostic("Unsupported LValue: $tokenType", DiagnosticKind.VariableExpected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// T is a PSI or a light-tree node
|
// T is a PSI or a light-tree node
|
||||||
|
@OptIn(FirContractViolation::class)
|
||||||
fun T?.generateAssignment(
|
fun T?.generateAssignment(
|
||||||
baseSource: KtSourceElement?,
|
baseSource: KtSourceElement?,
|
||||||
arrayAccessSource: KtSourceElement?,
|
arrayAccessSource: KtSourceElement?,
|
||||||
@@ -1010,10 +974,18 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val assignmentLValue = unwrappedLhs.convert()
|
||||||
return buildVariableAssignment {
|
return buildVariableAssignment {
|
||||||
source = baseSource
|
source = baseSource
|
||||||
|
lValue = if (baseSource?.kind == KtFakeSourceElementKind.DesugaredIncrementOrDecrement) {
|
||||||
|
buildDesugaredAssignmentValueReferenceExpression {
|
||||||
|
expressionRef = FirExpressionRef<FirExpression>().apply { bind(assignmentLValue) }
|
||||||
|
source = assignmentLValue.source?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assignmentLValue
|
||||||
|
}
|
||||||
rValue = rhsExpression
|
rValue = rhsExpression
|
||||||
calleeReference = initializeLValue(unwrappedLhs) { convert() as? FirQualifiedAccess }
|
|
||||||
this.annotations += annotations
|
this.annotations += annotations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1025,13 +997,12 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
rhsExpression: FirExpression,
|
rhsExpression: FirExpression,
|
||||||
annotations: List<FirAnnotation>
|
annotations: List<FirAnnotation>
|
||||||
): FirSafeCallExpression {
|
): FirSafeCallExpression {
|
||||||
val nestedAccess = safeCallNonAssignment.selector as FirQualifiedAccess
|
val nestedAccess = safeCallNonAssignment.selector as FirQualifiedAccessExpression
|
||||||
|
|
||||||
val assignment = buildVariableAssignment {
|
val assignment = buildVariableAssignment {
|
||||||
source = baseSource
|
source = baseSource
|
||||||
|
lValue = nestedAccess
|
||||||
rValue = rhsExpression
|
rValue = rhsExpression
|
||||||
calleeReference = nestedAccess.calleeReference
|
|
||||||
explicitReceiver = safeCallNonAssignment.checkedSubjectRef.value
|
|
||||||
this.annotations += annotations
|
this.annotations += annotations
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1228,10 +1199,10 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun convertFirSelector(
|
protected fun convertFirSelector(
|
||||||
firSelector: FirQualifiedAccess,
|
firSelector: FirQualifiedAccessExpression,
|
||||||
source: KtSourceElement?,
|
source: KtSourceElement?,
|
||||||
receiver: FirExpression
|
receiver: FirExpression
|
||||||
): FirQualifiedAccess {
|
): FirQualifiedAccessExpression {
|
||||||
return if (firSelector is FirImplicitInvokeCall) {
|
return if (firSelector is FirImplicitInvokeCall) {
|
||||||
buildImplicitInvokeCall {
|
buildImplicitInvokeCall {
|
||||||
this.source = source
|
this.source = source
|
||||||
|
|||||||
+2
-2
@@ -531,7 +531,7 @@ private fun FirExpression.checkReceiver(name: String?): Boolean {
|
|||||||
// this = .f(...)
|
// this = .f(...)
|
||||||
// receiver = <expr>
|
// receiver = <expr>
|
||||||
// Returns safe call <expr>?.{ f(...) }
|
// Returns safe call <expr>?.{ f(...) }
|
||||||
fun FirQualifiedAccess.createSafeCall(receiver: FirExpression, source: KtSourceElement): FirSafeCallExpression {
|
fun FirQualifiedAccessExpression.createSafeCall(receiver: FirExpression, source: KtSourceElement): FirSafeCallExpression {
|
||||||
val checkedSafeCallSubject = buildCheckedSafeCallSubject {
|
val checkedSafeCallSubject = buildCheckedSafeCallSubject {
|
||||||
@OptIn(FirContractViolation::class)
|
@OptIn(FirContractViolation::class)
|
||||||
this.originalReceiverRef = FirExpressionRef<FirExpression>().apply {
|
this.originalReceiverRef = FirExpressionRef<FirExpression>().apply {
|
||||||
@@ -555,7 +555,7 @@ fun FirQualifiedAccess.createSafeCall(receiver: FirExpression, source: KtSourceE
|
|||||||
// Turns (a?.b).f(...) to a?.{ b.f(...) ) -- for any qualified access `.f(...)`
|
// Turns (a?.b).f(...) to a?.{ b.f(...) ) -- for any qualified access `.f(...)`
|
||||||
// Other patterns remain unchanged
|
// Other patterns remain unchanged
|
||||||
fun FirExpression.pullUpSafeCallIfNecessary(): FirExpression {
|
fun FirExpression.pullUpSafeCallIfNecessary(): FirExpression {
|
||||||
if (this !is FirQualifiedAccess) return this
|
if (this !is FirQualifiedAccessExpression) return this
|
||||||
val safeCall = explicitReceiver as? FirSafeCallExpression ?: return this
|
val safeCall = explicitReceiver as? FirSafeCallExpression ?: return this
|
||||||
val safeCallSelector = safeCall.selector as? FirExpression ?: return this
|
val safeCallSelector = safeCall.selector as? FirExpression ?: return this
|
||||||
|
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ class FirCallResolver(
|
|||||||
)
|
)
|
||||||
|
|
||||||
/** WARNING: This function is public for the analysis API and should only be used there. */
|
/** WARNING: This function is public for the analysis API and should only be used there. */
|
||||||
fun <T : FirQualifiedAccess> collectAllCandidates(
|
fun collectAllCandidates(
|
||||||
qualifiedAccess: T,
|
qualifiedAccess: FirQualifiedAccessExpression,
|
||||||
name: Name,
|
name: Name,
|
||||||
containingDeclarations: List<FirDeclaration> = transformer.components.containingDeclarations,
|
containingDeclarations: List<FirDeclaration> = transformer.components.containingDeclarations,
|
||||||
resolutionContext: ResolutionContext = transformer.resolutionContext
|
resolutionContext: ResolutionContext = transformer.resolutionContext
|
||||||
@@ -134,21 +134,22 @@ class FirCallResolver(
|
|||||||
return collector.allCandidates.map { OverloadCandidate(it, isInBestCandidates = it in result.candidates) }
|
return collector.allCandidates.map { OverloadCandidate(it, isInBestCandidates = it in result.candidates) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : FirQualifiedAccess> collectCandidates(
|
private fun collectCandidates(
|
||||||
qualifiedAccess: T,
|
qualifiedAccess: FirQualifiedAccessExpression,
|
||||||
name: Name,
|
name: Name,
|
||||||
forceCallKind: CallKind? = null,
|
forceCallKind: CallKind? = null,
|
||||||
origin: FirFunctionCallOrigin = FirFunctionCallOrigin.Regular,
|
origin: FirFunctionCallOrigin = FirFunctionCallOrigin.Regular,
|
||||||
containingDeclarations: List<FirDeclaration> = transformer.components.containingDeclarations,
|
containingDeclarations: List<FirDeclaration> = transformer.components.containingDeclarations,
|
||||||
resolutionContext: ResolutionContext = transformer.resolutionContext,
|
resolutionContext: ResolutionContext = transformer.resolutionContext,
|
||||||
collector: CandidateCollector? = null
|
collector: CandidateCollector? = null,
|
||||||
|
callSite: FirElement = qualifiedAccess,
|
||||||
): ResolutionResult {
|
): ResolutionResult {
|
||||||
val explicitReceiver = qualifiedAccess.explicitReceiver
|
val explicitReceiver = qualifiedAccess.explicitReceiver
|
||||||
val argumentList = (qualifiedAccess as? FirFunctionCall)?.argumentList ?: FirEmptyArgumentList
|
val argumentList = (qualifiedAccess as? FirFunctionCall)?.argumentList ?: FirEmptyArgumentList
|
||||||
val typeArguments = (qualifiedAccess as? FirFunctionCall)?.typeArguments.orEmpty()
|
val typeArguments = (qualifiedAccess as? FirFunctionCall)?.typeArguments.orEmpty()
|
||||||
|
|
||||||
val info = CallInfo(
|
val info = CallInfo(
|
||||||
qualifiedAccess,
|
callSite,
|
||||||
forceCallKind ?: if (qualifiedAccess is FirFunctionCall) CallKind.Function else CallKind.VariableAccess,
|
forceCallKind ?: if (qualifiedAccess is FirFunctionCall) CallKind.Function else CallKind.VariableAccess,
|
||||||
name,
|
name,
|
||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
@@ -188,8 +189,12 @@ class FirCallResolver(
|
|||||||
return ResolutionResult(info, result.currentApplicability, reducedCandidates)
|
return ResolutionResult(info, result.currentApplicability, reducedCandidates)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : FirQualifiedAccess> resolveVariableAccessAndSelectCandidate(qualifiedAccess: T, isUsedAsReceiver: Boolean): FirStatement {
|
fun resolveVariableAccessAndSelectCandidate(
|
||||||
return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess, isUsedAsReceiver) { true }
|
qualifiedAccess: FirQualifiedAccessExpression,
|
||||||
|
isUsedAsReceiver: Boolean,
|
||||||
|
callSite: FirElement,
|
||||||
|
): FirStatement {
|
||||||
|
return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess, isUsedAsReceiver, callSite) { true }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resolveOnlyEnumOrQualifierAccessAndSelectCandidate(
|
fun resolveOnlyEnumOrQualifierAccessAndSelectCandidate(
|
||||||
@@ -202,19 +207,20 @@ class FirCallResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : FirQualifiedAccess> resolveVariableAccessAndSelectCandidateImpl(
|
private fun resolveVariableAccessAndSelectCandidateImpl(
|
||||||
qualifiedAccess: T,
|
qualifiedAccess: FirQualifiedAccessExpression,
|
||||||
isUsedAsReceiver: Boolean,
|
isUsedAsReceiver: Boolean,
|
||||||
acceptCandidates: (Collection<Candidate>) -> Boolean
|
callSite: FirElement = qualifiedAccess,
|
||||||
|
acceptCandidates: (Collection<Candidate>) -> Boolean,
|
||||||
): FirStatement {
|
): FirStatement {
|
||||||
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
|
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
|
||||||
|
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
val qualifiedAccess = transformer.transformExplicitReceiver(qualifiedAccess)
|
val qualifiedAccess = qualifiedAccess.let(transformer::transformExplicitReceiver)
|
||||||
val nonFatalDiagnosticFromExpression = (qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics
|
val nonFatalDiagnosticFromExpression = (qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics
|
||||||
|
|
||||||
val basicResult by lazy(LazyThreadSafetyMode.NONE) {
|
val basicResult by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
collectCandidates(qualifiedAccess, callee.name)
|
collectCandidates(qualifiedAccess, callee.name, callSite = callSite)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even if it's not receiver, it makes sense to continue qualifier if resolution is unsuccessful
|
// Even if it's not receiver, it makes sense to continue qualifier if resolution is unsuccessful
|
||||||
@@ -327,7 +333,7 @@ class FirCallResolver(
|
|||||||
replaceContextReceiverArguments(candidate.contextReceiverArguments())
|
replaceContextReceiverArguments(candidate.contextReceiverArguments())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (qualifiedAccess is FirExpression) transformer.storeTypeFromCallee(qualifiedAccess)
|
transformer.storeTypeFromCallee(qualifiedAccess, isLhsOfAssignment = callSite is FirVariableAssignment)
|
||||||
return qualifiedAccess
|
return qualifiedAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve
|
package org.jetbrains.kotlin.fir.resolve
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode.Companion.prettyString
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
|
|
||||||
@@ -86,6 +86,10 @@ sealed class ResolutionMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AssignmentLValue(val variableAssignment: FirVariableAssignment) : ResolutionMode() {
|
||||||
|
override fun toString(): String = "AssignmentLValue: ${variableAssignment.render()}"
|
||||||
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
private fun FirTypeRef?.prettyString(): String {
|
private fun FirTypeRef?.prettyString(): String {
|
||||||
if (this == null) return "null"
|
if (this == null) return "null"
|
||||||
@@ -98,6 +102,7 @@ sealed class ResolutionMode {
|
|||||||
fun ResolutionMode.expectedType(components: BodyResolveComponents, allowFromCast: Boolean = false): FirTypeRef? = when (this) {
|
fun ResolutionMode.expectedType(components: BodyResolveComponents, allowFromCast: Boolean = false): FirTypeRef? = when (this) {
|
||||||
is ResolutionMode.WithExpectedType -> expectedTypeRef
|
is ResolutionMode.WithExpectedType -> expectedTypeRef
|
||||||
is ResolutionMode.ContextIndependent,
|
is ResolutionMode.ContextIndependent,
|
||||||
|
is ResolutionMode.AssignmentLValue,
|
||||||
is ResolutionMode.ReceiverResolution -> components.noExpectedType
|
is ResolutionMode.ReceiverResolution -> components.noExpectedType
|
||||||
is ResolutionMode.WithExpectedTypeFromCast -> expectedTypeRef.takeIf { allowFromCast }
|
is ResolutionMode.WithExpectedTypeFromCast -> expectedTypeRef.takeIf { allowFromCast }
|
||||||
is ResolutionMode.WithSuggestedType -> suggestedTypeRef
|
is ResolutionMode.WithSuggestedType -> suggestedTypeRef
|
||||||
|
|||||||
@@ -25,10 +25,7 @@ import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
|||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirPropertyWithExplicitBackingFieldResolvedNamedReference
|
import org.jetbrains.kotlin.fir.resolve.calls.FirPropertyWithExplicitBackingFieldResolvedNamedReference
|
||||||
@@ -289,24 +286,29 @@ private fun FirPropertyWithExplicitBackingFieldResolvedNamedReference.getNarrowe
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirResolvedTypeRef {
|
fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirResolvedTypeRef {
|
||||||
return when (val newCallee = access.calleeReference) {
|
val calleeReference = access.calleeReference
|
||||||
|
return typeFromCallee(access, calleeReference)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun BodyResolveComponents.typeFromCallee(access: FirElement, calleeReference: FirReference): FirResolvedTypeRef {
|
||||||
|
return when (calleeReference) {
|
||||||
is FirErrorNamedReference ->
|
is FirErrorNamedReference ->
|
||||||
buildErrorTypeRef {
|
buildErrorTypeRef {
|
||||||
source = access.source?.fakeElement(KtFakeSourceElementKind.ErrorTypeRef)
|
source = access.source?.fakeElement(KtFakeSourceElementKind.ErrorTypeRef)
|
||||||
diagnostic = ConeStubDiagnostic(newCallee.diagnostic)
|
diagnostic = ConeStubDiagnostic(calleeReference.diagnostic)
|
||||||
}
|
}
|
||||||
is FirNamedReferenceWithCandidate -> {
|
is FirNamedReferenceWithCandidate -> {
|
||||||
typeFromSymbol(newCallee.candidateSymbol, false)
|
typeFromSymbol(calleeReference.candidateSymbol, false)
|
||||||
}
|
}
|
||||||
is FirPropertyWithExplicitBackingFieldResolvedNamedReference -> {
|
is FirPropertyWithExplicitBackingFieldResolvedNamedReference -> {
|
||||||
val symbol = newCallee.getNarrowedDownSymbol(session)
|
val symbol = calleeReference.getNarrowedDownSymbol(session)
|
||||||
typeFromSymbol(symbol, false)
|
typeFromSymbol(symbol, false)
|
||||||
}
|
}
|
||||||
is FirResolvedNamedReference -> {
|
is FirResolvedNamedReference -> {
|
||||||
typeFromSymbol(newCallee.resolvedSymbol, false)
|
typeFromSymbol(calleeReference.resolvedSymbol, false)
|
||||||
}
|
}
|
||||||
is FirThisReference -> {
|
is FirThisReference -> {
|
||||||
val labelName = newCallee.labelName
|
val labelName = calleeReference.labelName
|
||||||
val implicitReceiver = implicitReceiverStack[labelName]
|
val implicitReceiver = implicitReceiverStack[labelName]
|
||||||
buildResolvedTypeRef {
|
buildResolvedTypeRef {
|
||||||
source = null
|
source = null
|
||||||
@@ -319,19 +321,19 @@ fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirReso
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FirSuperReference -> {
|
is FirSuperReference -> {
|
||||||
val labelName = newCallee.labelName
|
val labelName = calleeReference.labelName
|
||||||
val implicitReceiver =
|
val implicitReceiver =
|
||||||
if (labelName != null) implicitReceiverStack[labelName] as? ImplicitDispatchReceiverValue
|
if (labelName != null) implicitReceiverStack[labelName] as? ImplicitDispatchReceiverValue
|
||||||
else implicitReceiverStack.lastDispatchReceiver()
|
else implicitReceiverStack.lastDispatchReceiver()
|
||||||
val resolvedTypeRef =
|
val resolvedTypeRef =
|
||||||
newCallee.superTypeRef as? FirResolvedTypeRef
|
calleeReference.superTypeRef as? FirResolvedTypeRef
|
||||||
?: implicitReceiver?.boundSymbol?.fir?.superTypeRefs?.singleOrNull() as? FirResolvedTypeRef
|
?: implicitReceiver?.boundSymbol?.fir?.superTypeRefs?.singleOrNull() as? FirResolvedTypeRef
|
||||||
resolvedTypeRef ?: buildErrorTypeRef {
|
resolvedTypeRef ?: buildErrorTypeRef {
|
||||||
source = newCallee.source
|
source = calleeReference.source
|
||||||
diagnostic = ConeUnresolvedNameError(Name.identifier("super"))
|
diagnostic = ConeUnresolvedNameError(Name.identifier("super"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> error("Failed to extract type from: $newCallee")
|
else -> error("Failed to extract type from: $calleeReference")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,6 +399,7 @@ private fun FirSmartCastExpressionBuilder.applyResultTypeRef() {
|
|||||||
else
|
else
|
||||||
originalExpression.typeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
|
originalExpression.typeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : FirExpression> BodyResolveComponents.transformExpressionUsingSmartcastInfo(
|
private fun <T : FirExpression> BodyResolveComponents.transformExpressionUsingSmartcastInfo(
|
||||||
expression: T,
|
expression: T,
|
||||||
stability: PropertyStability,
|
stability: PropertyStability,
|
||||||
@@ -528,22 +531,15 @@ fun FirAnnotation.getCorrespondingClassSymbolOrNull(session: FirSession): FirReg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> BodyResolveComponents.initialTypeOfCandidate(
|
|
||||||
candidate: Candidate,
|
|
||||||
call: T
|
|
||||||
): ConeKotlinType where T : FirResolvable, T : FirStatement {
|
|
||||||
return initialTypeOfCandidate(candidate, typeFromCallee(call))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun BodyResolveComponents.initialTypeOfCandidate(candidate: Candidate): ConeKotlinType {
|
fun BodyResolveComponents.initialTypeOfCandidate(candidate: Candidate): ConeKotlinType {
|
||||||
val typeRef = typeFromSymbol(candidate.symbol, makeNullable = false)
|
val typeRef = typeFromSymbol(candidate.symbol, makeNullable = false)
|
||||||
return initialTypeOfCandidate(candidate, typeRef)
|
return typeRef.initialTypeOfCandidate(candidate)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initialTypeOfCandidate(candidate: Candidate, typeRef: FirResolvedTypeRef): ConeKotlinType {
|
fun FirResolvedTypeRef.initialTypeOfCandidate(candidate: Candidate): ConeKotlinType {
|
||||||
val system = candidate.system
|
val system = candidate.system
|
||||||
val resultingSubstitutor = system.buildCurrentSubstitutor()
|
val resultingSubstitutor = system.buildCurrentSubstitutor()
|
||||||
return resultingSubstitutor.safeSubstitute(system, candidate.substitutor.substituteOrSelf(typeRef.type)) as ConeKotlinType
|
return resultingSubstitutor.safeSubstitute(system, candidate.substitutor.substituteOrSelf(type)) as ConeKotlinType
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirCallableDeclaration.getContainingClass(session: FirSession): FirRegularClass? =
|
fun FirCallableDeclaration.getContainingClass(session: FirSession): FirRegularClass? =
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirVariable
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||||
import org.jetbrains.kotlin.fir.dispatchReceiverClassLookupTagOrNull
|
import org.jetbrains.kotlin.fir.dispatchReceiverClassLookupTagOrNull
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.scope
|
import org.jetbrains.kotlin.fir.resolve.scope
|
||||||
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
|||||||
|
|
||||||
fun BodyResolveComponents.findTypesForSuperCandidates(
|
fun BodyResolveComponents.findTypesForSuperCandidates(
|
||||||
superTypeRefs: List<FirTypeRef>,
|
superTypeRefs: List<FirTypeRef>,
|
||||||
containingCall: FirQualifiedAccess,
|
containingCall: FirQualifiedAccessExpression,
|
||||||
): List<ConeKotlinType> {
|
): List<ConeKotlinType> {
|
||||||
val supertypes = superTypeRefs.map { (it as FirResolvedTypeRef).type }
|
val supertypes = superTypeRefs.map { (it as FirResolvedTypeRef).type }
|
||||||
val isMethodOfAny = containingCall is FirFunctionCall && isCallingMethodOfAny(containingCall)
|
val isMethodOfAny = containingCall is FirFunctionCall && isCallingMethodOfAny(containingCall)
|
||||||
|
|||||||
+20
-12
@@ -794,9 +794,17 @@ abstract class FirDataFlowAnalyzer(
|
|||||||
graphBuilder.exitStringConcatenationCall(call).mergeIncomingFlow()
|
graphBuilder.exitStringConcatenationCall(call).mergeIncomingFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirQualifiedAccess.orderedArguments(callee: FirFunction): Array<out FirExpression?>? {
|
private fun FirStatement.orderedArguments(callee: FirFunction): Array<out FirExpression?>? {
|
||||||
val receiver = extensionReceiver.takeIf { it != FirNoReceiverExpression }
|
fun FirQualifiedAccessExpression.firstReceiver(): FirExpression? =
|
||||||
?: dispatchReceiver.takeIf { it != FirNoReceiverExpression }
|
(extensionReceiver.takeIf { it != FirNoReceiverExpression }
|
||||||
|
?: dispatchReceiver.takeIf { it != FirNoReceiverExpression })
|
||||||
|
|
||||||
|
val receiver = when (this) {
|
||||||
|
is FirQualifiedAccessExpression -> firstReceiver()
|
||||||
|
is FirVariableAssignment -> (lValue as? FirQualifiedAccessExpression)?.firstReceiver()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FirFunctionCall -> {
|
is FirFunctionCall -> {
|
||||||
val argumentToParameter = resolvedArgumentMapping ?: return null
|
val argumentToParameter = resolvedArgumentMapping ?: return null
|
||||||
@@ -811,11 +819,11 @@ abstract class FirDataFlowAnalyzer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processConditionalContract(flow: MutableFlow, qualifiedAccess: FirQualifiedAccess) {
|
private fun processConditionalContract(flow: MutableFlow, qualifiedAccess: FirStatement) {
|
||||||
val callee = when (qualifiedAccess) {
|
val callee = when (qualifiedAccess) {
|
||||||
is FirFunctionCall -> qualifiedAccess.toResolvedCallableSymbol()?.fir as? FirSimpleFunction
|
is FirFunctionCall -> qualifiedAccess.toResolvedCallableSymbol()?.fir as? FirSimpleFunction
|
||||||
is FirQualifiedAccessExpression -> qualifiedAccess.calleeReference.toResolvedPropertySymbol()?.fir?.getter
|
is FirQualifiedAccessExpression -> qualifiedAccess.calleeReference.toResolvedPropertySymbol()?.fir?.getter
|
||||||
is FirVariableAssignment -> qualifiedAccess.lValue.toResolvedPropertySymbol()?.fir?.setter
|
is FirVariableAssignment -> qualifiedAccess.calleeReference?.toResolvedPropertySymbol()?.fir?.setter
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return
|
} ?: return
|
||||||
|
|
||||||
@@ -837,7 +845,7 @@ abstract class FirDataFlowAnalyzer(
|
|||||||
if (argumentVariables.all { it == null }) return
|
if (argumentVariables.all { it == null }) return
|
||||||
|
|
||||||
val typeParameters = callee.typeParameters
|
val typeParameters = callee.typeParameters
|
||||||
val substitutor = if (typeParameters.isNotEmpty()) {
|
val substitutor = if (typeParameters.isNotEmpty() && qualifiedAccess is FirQualifiedAccessExpression) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val substitutionFromArguments = typeParameters.zip(qualifiedAccess.typeArguments).map { (typeParameterRef, typeArgument) ->
|
val substitutionFromArguments = typeParameters.zip(qualifiedAccess.typeArguments).map { (typeParameterRef, typeArgument) ->
|
||||||
typeParameterRef.symbol to typeArgument.toConeTypeProjection().type
|
typeParameterRef.symbol to typeArgument.toConeTypeProjection().type
|
||||||
@@ -870,15 +878,15 @@ abstract class FirDataFlowAnalyzer(
|
|||||||
fun exitLocalVariableDeclaration(variable: FirProperty, hadExplicitType: Boolean) {
|
fun exitLocalVariableDeclaration(variable: FirProperty, hadExplicitType: Boolean) {
|
||||||
graphBuilder.exitVariableDeclaration(variable).mergeIncomingFlow { flow ->
|
graphBuilder.exitVariableDeclaration(variable).mergeIncomingFlow { flow ->
|
||||||
val initializer = variable.initializer ?: return@mergeIncomingFlow
|
val initializer = variable.initializer ?: return@mergeIncomingFlow
|
||||||
exitVariableInitialization(flow, initializer, variable, assignment = null, hadExplicitType)
|
exitVariableInitialization(flow, initializer, variable, assignmentLhs = null, hadExplicitType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exitVariableAssignment(assignment: FirVariableAssignment) {
|
fun exitVariableAssignment(assignment: FirVariableAssignment) {
|
||||||
graphBuilder.exitVariableAssignment(assignment).mergeIncomingFlow { flow ->
|
graphBuilder.exitVariableAssignment(assignment).mergeIncomingFlow { flow ->
|
||||||
val property = assignment.lValue.toResolvedPropertySymbol()?.fir ?: return@mergeIncomingFlow
|
val property = assignment.calleeReference?.toResolvedPropertySymbol()?.fir ?: return@mergeIncomingFlow
|
||||||
if (property.isLocal || property.isVal) {
|
if (property.isLocal || property.isVal) {
|
||||||
exitVariableInitialization(flow, assignment.rValue, property, assignment, hasExplicitType = false)
|
exitVariableInitialization(flow, assignment.rValue, property, assignment.lValue, hasExplicitType = false)
|
||||||
} else {
|
} else {
|
||||||
// TODO: add unstable smartcast for non-local var
|
// TODO: add unstable smartcast for non-local var
|
||||||
val variable = variableStorage.getRealVariableWithoutUnwrappingAlias(flow, assignment)
|
val variable = variableStorage.getRealVariableWithoutUnwrappingAlias(flow, assignment)
|
||||||
@@ -894,16 +902,16 @@ abstract class FirDataFlowAnalyzer(
|
|||||||
flow: MutableFlow,
|
flow: MutableFlow,
|
||||||
initializer: FirExpression,
|
initializer: FirExpression,
|
||||||
property: FirProperty,
|
property: FirProperty,
|
||||||
assignment: FirVariableAssignment?,
|
assignmentLhs: FirExpression?,
|
||||||
hasExplicitType: Boolean,
|
hasExplicitType: Boolean,
|
||||||
) {
|
) {
|
||||||
val propertyVariable = variableStorage.getOrCreateRealVariableWithoutUnwrappingAlias(
|
val propertyVariable = variableStorage.getOrCreateRealVariableWithoutUnwrappingAlias(
|
||||||
flow,
|
flow,
|
||||||
property.symbol,
|
property.symbol,
|
||||||
assignment ?: property,
|
assignmentLhs ?: property,
|
||||||
if (property.isVal) PropertyStability.STABLE_VALUE else PropertyStability.LOCAL_VAR
|
if (property.isVal) PropertyStability.STABLE_VALUE else PropertyStability.LOCAL_VAR
|
||||||
)
|
)
|
||||||
val isAssignment = assignment != null
|
val isAssignment = assignmentLhs != null
|
||||||
if (isAssignment) {
|
if (isAssignment) {
|
||||||
logicSystem.recordNewAssignment(flow, propertyVariable, context.newAssignmentIndex())
|
logicSystem.recordNewAssignment(flow, propertyVariable, context.newAssignmentIndex())
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.references.FirReference
|
|||||||
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.explicitReceiver
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
@@ -380,7 +381,7 @@ internal class FirLocalVariableAssignmentAnalyzer {
|
|||||||
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: MiniCfgData) {
|
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: MiniCfgData) {
|
||||||
visitElement(variableAssignment, data)
|
visitElement(variableAssignment, data)
|
||||||
if (variableAssignment.explicitReceiver != null) return
|
if (variableAssignment.explicitReceiver != null) return
|
||||||
data.recordAssignment(variableAssignment.lValue)
|
variableAssignment.calleeReference?.let { data.recordAssignment(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAssignmentOperatorStatement(assignmentOperatorStatement: FirAssignmentOperatorStatement, data: MiniCfgData) {
|
override fun visitAssignmentOperatorStatement(assignmentOperatorStatement: FirAssignmentOperatorStatement, data: MiniCfgData) {
|
||||||
|
|||||||
+2
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirElement
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.explicitReceiver
|
||||||
import org.jetbrains.kotlin.fir.util.SetMultimap
|
import org.jetbrains.kotlin.fir.util.SetMultimap
|
||||||
import org.jetbrains.kotlin.fir.util.setMultimapOf
|
import org.jetbrains.kotlin.fir.util.setMultimapOf
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
@@ -48,7 +49,7 @@ class PreliminaryLoopVisitor {
|
|||||||
// property assignment, the smart cast will be unstable anyway.
|
// property assignment, the smart cast will be unstable anyway.
|
||||||
if (variableAssignment.explicitReceiver != null) return
|
if (variableAssignment.explicitReceiver != null) return
|
||||||
|
|
||||||
val reference = variableAssignment.lValue as? FirNamedReference
|
val reference = variableAssignment.calleeReference as? FirNamedReference
|
||||||
if (reference != null) {
|
if (reference != null) {
|
||||||
requireNotNull(data)
|
requireNotNull(data)
|
||||||
reassignedVariablesPerElement.put(data, reference.name)
|
reassignedVariablesPerElement.put(data, reference.name)
|
||||||
|
|||||||
+1
-1
@@ -503,7 +503,7 @@ fun FirStatement.processAllContainingCallCandidates(processBlocks: Boolean, proc
|
|||||||
}
|
}
|
||||||
|
|
||||||
is FirVariableAssignment -> {
|
is FirVariableAssignment -> {
|
||||||
processCandidateIfApplicable(processor, processBlocks)
|
(lValue as? FirResolvable)?.processCandidateIfApplicable(processor, processBlocks)
|
||||||
rValue.processAllContainingCallCandidates(processBlocks, processor)
|
rValue.processAllContainingCallCandidates(processBlocks, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-6
@@ -81,7 +81,8 @@ class FirCallCompleter(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun <T> completeCall(
|
private fun <T> completeCall(
|
||||||
call: T, expectedTypeRef: FirTypeRef?,
|
call: T,
|
||||||
|
expectedTypeRef: FirTypeRef?,
|
||||||
mayBeCoercionToUnitApplied: Boolean,
|
mayBeCoercionToUnitApplied: Boolean,
|
||||||
expectedTypeMismatchIsReportedInChecker: Boolean,
|
expectedTypeMismatchIsReportedInChecker: Boolean,
|
||||||
isFromCast: Boolean,
|
isFromCast: Boolean,
|
||||||
@@ -90,14 +91,10 @@ class FirCallCompleter(
|
|||||||
where T : FirResolvable, T : FirStatement {
|
where T : FirResolvable, T : FirStatement {
|
||||||
val typeRef = components.typeFromCallee(call)
|
val typeRef = components.typeFromCallee(call)
|
||||||
|
|
||||||
if (call is FirVariableAssignment) {
|
|
||||||
call.replaceLValueTypeRef(typeRef)
|
|
||||||
}
|
|
||||||
|
|
||||||
val reference = call.calleeReference as? FirNamedReferenceWithCandidate ?: return CompletionResult(call, true)
|
val reference = call.calleeReference as? FirNamedReferenceWithCandidate ?: return CompletionResult(call, true)
|
||||||
|
|
||||||
val candidate = reference.candidate
|
val candidate = reference.candidate
|
||||||
val initialType = components.initialTypeOfCandidate(candidate, call)
|
val initialType = typeRef.initialTypeOfCandidate(candidate)
|
||||||
|
|
||||||
if (call is FirExpression) {
|
if (call is FirExpression) {
|
||||||
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(initialType)
|
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(initialType)
|
||||||
|
|||||||
+4
-27
@@ -83,7 +83,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : FirQualifiedAccess> prepareQualifiedTransform(
|
private fun <T : FirQualifiedAccessExpression> prepareQualifiedTransform(
|
||||||
qualifiedAccessExpression: T, calleeReference: FirNamedReferenceWithCandidate
|
qualifiedAccessExpression: T, calleeReference: FirNamedReferenceWithCandidate
|
||||||
): T {
|
): T {
|
||||||
val subCandidate = calleeReference.candidate
|
val subCandidate = calleeReference.candidate
|
||||||
@@ -129,7 +129,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
extensionReceiver = extensionReceiver.transformSingle(integerOperatorApproximator, expectedExtensionReceiverType)
|
extensionReceiver = extensionReceiver.transformSingle(integerOperatorApproximator, expectedExtensionReceiverType)
|
||||||
}
|
}
|
||||||
|
|
||||||
qualifiedAccessExpression.apply {
|
(qualifiedAccessExpression as? FirQualifiedAccessExpression)?.apply {
|
||||||
replaceCalleeReference(calleeReference.toResolvedReference())
|
replaceCalleeReference(calleeReference.toResolvedReference())
|
||||||
replaceDispatchReceiver(dispatchReceiver)
|
replaceDispatchReceiver(dispatchReceiver)
|
||||||
replaceExtensionReceiver(extensionReceiver)
|
replaceExtensionReceiver(extensionReceiver)
|
||||||
@@ -146,11 +146,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
qualifiedAccessExpression.replaceNonFatalDiagnostics(nonFatalDiagnostics)
|
qualifiedAccessExpression.replaceNonFatalDiagnostics(nonFatalDiagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qualifiedAccessExpression is FirQualifiedAccessExpression) {
|
qualifiedAccessExpression.replaceTypeRef(typeRef)
|
||||||
qualifiedAccessExpression.replaceTypeRef(typeRef)
|
|
||||||
} else if (qualifiedAccessExpression is FirVariableAssignment) {
|
|
||||||
qualifiedAccessExpression.replaceLValueTypeRef(typeRef)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (declaration !is FirErrorFunction) {
|
if (declaration !is FirErrorFunction) {
|
||||||
qualifiedAccessExpression.replaceTypeArguments(typeArguments)
|
qualifiedAccessExpression.replaceTypeArguments(typeArguments)
|
||||||
@@ -405,25 +401,6 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformVariableAssignment(
|
|
||||||
variableAssignment: FirVariableAssignment,
|
|
||||||
data: ExpectedArgumentType?,
|
|
||||||
): FirStatement {
|
|
||||||
val calleeReference = variableAssignment.calleeReference as? FirNamedReferenceWithCandidate ?: return variableAssignment
|
|
||||||
|
|
||||||
// Initialize lValueTypeRef
|
|
||||||
val qualifiedTransform = prepareQualifiedTransform(variableAssignment, calleeReference)
|
|
||||||
val lValueTypeRef = qualifiedTransform.lValueTypeRef as FirResolvedTypeRef
|
|
||||||
val resultLValueType = lValueTypeRef.substituteTypeRef(calleeReference.candidate)
|
|
||||||
resultLValueType.ensureResolvedTypeDeclaration(session)
|
|
||||||
variableAssignment.replaceLValueTypeRef(resultLValueType)
|
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(resultLValueType, variableAssignment.lValue.source, context.file.source)
|
|
||||||
|
|
||||||
return variableAssignment.apply {
|
|
||||||
replaceCalleeReference(calleeReference.toResolvedReference())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun transformSmartCastExpression(smartCastExpression: FirSmartCastExpression, data: ExpectedArgumentType?): FirStatement {
|
override fun transformSmartCastExpression(smartCastExpression: FirSmartCastExpression, data: ExpectedArgumentType?): FirStatement {
|
||||||
return smartCastExpression.transformOriginalExpression(this, data)
|
return smartCastExpression.transformOriginalExpression(this, data)
|
||||||
}
|
}
|
||||||
@@ -509,7 +486,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun computeTypeArguments(
|
private fun computeTypeArguments(
|
||||||
access: FirQualifiedAccess,
|
access: FirQualifiedAccessExpression,
|
||||||
candidate: Candidate
|
candidate: Candidate
|
||||||
): List<FirTypeProjection> {
|
): List<FirTypeProjection> {
|
||||||
val typeArguments = computeTypeArgumentTypes(candidate)
|
val typeArguments = computeTypeArgumentTypes(candidate)
|
||||||
|
|||||||
+7
@@ -181,6 +181,13 @@ abstract class FirAbstractBodyResolveTransformerDispatcher(
|
|||||||
return expressionsTransformer.transformBinaryLogicExpression(binaryLogicExpression, data)
|
return expressionsTransformer.transformBinaryLogicExpression(binaryLogicExpression, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun transformDesugaredAssignmentValueReferenceExpression(
|
||||||
|
desugaredAssignmentValueReferenceExpression: FirDesugaredAssignmentValueReferenceExpression,
|
||||||
|
data: ResolutionMode
|
||||||
|
): FirStatement {
|
||||||
|
return expressionsTransformer.transformDesugaredAssignmentValueReferenceExpression(desugaredAssignmentValueReferenceExpression, data)
|
||||||
|
}
|
||||||
|
|
||||||
override fun transformVariableAssignment(
|
override fun transformVariableAssignment(
|
||||||
variableAssignment: FirVariableAssignment,
|
variableAssignment: FirVariableAssignment,
|
||||||
data: ResolutionMode
|
data: ResolutionMode
|
||||||
|
|||||||
+2
-3
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctiona
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolver
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolver
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.toExpectedType
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.transformVarargTypeToArrayType
|
import org.jetbrains.kotlin.fir.resolve.transformers.transformVarargTypeToArrayType
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
|
||||||
import org.jetbrains.kotlin.fir.types.constructStarProjectedType
|
import org.jetbrains.kotlin.fir.types.constructStarProjectedType
|
||||||
@@ -317,7 +316,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
|
|||||||
.transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null)
|
.transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null)
|
||||||
|
|
||||||
// Second, replace result type of delegate expression with stub type if delegate not yet resolved
|
// Second, replace result type of delegate expression with stub type if delegate not yet resolved
|
||||||
if (delegateExpression is FirQualifiedAccess) {
|
if (delegateExpression is FirQualifiedAccessExpression) {
|
||||||
val calleeReference = delegateExpression.calleeReference
|
val calleeReference = delegateExpression.calleeReference
|
||||||
if (calleeReference is FirNamedReferenceWithCandidate) {
|
if (calleeReference is FirNamedReferenceWithCandidate) {
|
||||||
val system = calleeReference.candidate.system
|
val system = calleeReference.candidate.system
|
||||||
@@ -736,7 +735,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
|
|||||||
transformAnonymousFunctionWithExpectedType(anonymousFunction, data.expectedTypeRef, data)
|
transformAnonymousFunctionWithExpectedType(anonymousFunction, data.expectedTypeRef, data)
|
||||||
is ResolutionMode.WithSuggestedType ->
|
is ResolutionMode.WithSuggestedType ->
|
||||||
transformAnonymousFunctionWithExpectedType(anonymousFunction, data.suggestedTypeRef, data)
|
transformAnonymousFunctionWithExpectedType(anonymousFunction, data.suggestedTypeRef, data)
|
||||||
is ResolutionMode.ContextIndependent, is ResolutionMode.ReceiverResolution ->
|
is ResolutionMode.ContextIndependent, is ResolutionMode.AssignmentLValue, is ResolutionMode.ReceiverResolution ->
|
||||||
transformAnonymousFunctionWithExpectedType(anonymousFunction, buildImplicitTypeRef(), data)
|
transformAnonymousFunctionWithExpectedType(anonymousFunction, buildImplicitTypeRef(), data)
|
||||||
is ResolutionMode.WithStatus, is ResolutionMode.WithExpectedTypeFromCast ->
|
is ResolutionMode.WithStatus, is ResolutionMode.WithExpectedTypeFromCast ->
|
||||||
throw AssertionError("Should not be here in WithStatus/WithExpectedTypeFromCast mode")
|
throw AssertionError("Should not be here in WithStatus/WithExpectedTypeFromCast mode")
|
||||||
|
|||||||
+107
-72
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.extensions.extensionService
|
|||||||
import org.jetbrains.kotlin.fir.references.*
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference
|
import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedErrorReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
@@ -133,7 +132,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
transformSuperReceiver(
|
transformSuperReceiver(
|
||||||
callee,
|
callee,
|
||||||
qualifiedAccessExpression,
|
qualifiedAccessExpression,
|
||||||
containingSafeCallExpression?.takeIf { qualifiedAccessExpression == it.receiver }?.selector as? FirQualifiedAccess
|
containingSafeCallExpression?.takeIf { qualifiedAccessExpression == it.receiver }?.selector as? FirQualifiedAccessExpression
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is FirDelegateFieldReference -> {
|
is FirDelegateFieldReference -> {
|
||||||
@@ -144,12 +143,19 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
is FirResolvedNamedReference,
|
is FirResolvedNamedReference,
|
||||||
is FirErrorNamedReference -> {
|
is FirErrorNamedReference -> {
|
||||||
if (qualifiedAccessExpression.typeRef !is FirResolvedTypeRef) {
|
if (qualifiedAccessExpression.typeRef !is FirResolvedTypeRef) {
|
||||||
storeTypeFromCallee(qualifiedAccessExpression)
|
storeTypeFromCallee(qualifiedAccessExpression, isLhsOfAssignment = false)
|
||||||
}
|
}
|
||||||
qualifiedAccessExpression
|
qualifiedAccessExpression
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val transformedCallee = resolveQualifiedAccessAndSelectCandidate(qualifiedAccessExpression, isUsedAsReceiver)
|
val transformedCallee = resolveQualifiedAccessAndSelectCandidate(
|
||||||
|
qualifiedAccessExpression,
|
||||||
|
isUsedAsReceiver,
|
||||||
|
when (data) {
|
||||||
|
is ResolutionMode.AssignmentLValue -> data.variableAssignment
|
||||||
|
else -> qualifiedAccessExpression
|
||||||
|
}
|
||||||
|
)
|
||||||
// NB: here we can get raw expression because of dropped qualifiers (see transform callee),
|
// NB: here we can get raw expression because of dropped qualifiers (see transform callee),
|
||||||
// so candidate existence must be checked before calling completion
|
// so candidate existence must be checked before calling completion
|
||||||
if (transformedCallee is FirQualifiedAccessExpression && transformedCallee.candidate() != null) {
|
if (transformedCallee is FirQualifiedAccessExpression && transformedCallee.candidate() != null) {
|
||||||
@@ -162,22 +168,24 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when (result) {
|
if (data !is ResolutionMode.AssignmentLValue) {
|
||||||
is FirQualifiedAccessExpression -> {
|
when (result) {
|
||||||
dataFlowAnalyzer.exitQualifiedAccessExpression(result)
|
is FirQualifiedAccessExpression -> {
|
||||||
result = components.transformQualifiedAccessUsingSmartcastInfo(result)
|
dataFlowAnalyzer.exitQualifiedAccessExpression(result)
|
||||||
if (result is FirSmartCastExpression) {
|
result = components.transformQualifiedAccessUsingSmartcastInfo(result)
|
||||||
dataFlowAnalyzer.exitSmartCastExpression(result)
|
if (result is FirSmartCastExpression) {
|
||||||
|
dataFlowAnalyzer.exitSmartCastExpression(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is FirResolvedQualifier -> {
|
||||||
|
dataFlowAnalyzer.exitResolvedQualifierNode(result)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
is FirResolvedQualifier -> {
|
|
||||||
dataFlowAnalyzer.exitResolvedQualifierNode(result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <Q : FirQualifiedAccess> transformExplicitReceiver(qualifiedAccessExpression: Q): Q {
|
fun <Q : FirQualifiedAccessExpression> transformExplicitReceiver(qualifiedAccessExpression: Q): Q {
|
||||||
val explicitReceiver = qualifiedAccessExpression.explicitReceiver as? FirQualifiedAccessExpression
|
val explicitReceiver = qualifiedAccessExpression.explicitReceiver as? FirQualifiedAccessExpression
|
||||||
if (explicitReceiver is FirQualifiedAccessExpression) {
|
if (explicitReceiver is FirQualifiedAccessExpression) {
|
||||||
val superReference = explicitReceiver.calleeReference as? FirSuperReference
|
val superReference = explicitReceiver.calleeReference as? FirSuperReference
|
||||||
@@ -208,14 +216,15 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
protected open fun resolveQualifiedAccessAndSelectCandidate(
|
protected open fun resolveQualifiedAccessAndSelectCandidate(
|
||||||
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||||
isUsedAsReceiver: Boolean,
|
isUsedAsReceiver: Boolean,
|
||||||
|
callSite: FirElement,
|
||||||
): FirStatement {
|
): FirStatement {
|
||||||
return callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression, isUsedAsReceiver)
|
return callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression, isUsedAsReceiver, callSite)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun transformSuperReceiver(
|
fun transformSuperReceiver(
|
||||||
superReference: FirSuperReference,
|
superReference: FirSuperReference,
|
||||||
superReferenceContainer: FirQualifiedAccessExpression,
|
superReferenceContainer: FirQualifiedAccessExpression,
|
||||||
containingCall: FirQualifiedAccess?
|
containingCall: FirQualifiedAccessExpression?
|
||||||
): FirQualifiedAccessExpression {
|
): FirQualifiedAccessExpression {
|
||||||
val labelName = superReference.labelName
|
val labelName = superReference.labelName
|
||||||
val lastDispatchReceiver = implicitReceiverStack.lastDispatchReceiver()
|
val lastDispatchReceiver = implicitReceiverStack.lastDispatchReceiver()
|
||||||
@@ -385,7 +394,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
(calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference) &&
|
(calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference) &&
|
||||||
functionCall.resultType is FirImplicitTypeRef
|
functionCall.resultType is FirImplicitTypeRef
|
||||||
) {
|
) {
|
||||||
storeTypeFromCallee(functionCall)
|
storeTypeFromCallee(functionCall, isLhsOfAssignment = false)
|
||||||
}
|
}
|
||||||
if (calleeReference is FirNamedReferenceWithCandidate) return functionCall
|
if (calleeReference is FirNamedReferenceWithCandidate) return functionCall
|
||||||
if (calleeReference !is FirSimpleNamedReference) {
|
if (calleeReference !is FirSimpleNamedReference) {
|
||||||
@@ -413,7 +422,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
}
|
}
|
||||||
val resultExpression = callResolver.resolveCallAndSelectCandidate(withTransformedArguments)
|
val resultExpression = callResolver.resolveCallAndSelectCandidate(withTransformedArguments)
|
||||||
val resultExplicitReceiver = resultExpression.explicitReceiver?.unwrapSmartcastExpression()
|
val resultExplicitReceiver = resultExpression.explicitReceiver?.unwrapSmartcastExpression()
|
||||||
if (initialExplicitReceiver !== resultExplicitReceiver && resultExplicitReceiver is FirQualifiedAccess) {
|
if (initialExplicitReceiver !== resultExplicitReceiver && resultExplicitReceiver is FirQualifiedAccessExpression) {
|
||||||
// name.invoke() case
|
// name.invoke() case
|
||||||
callCompleter.completeCall(resultExplicitReceiver, noExpectedType)
|
callCompleter.completeCall(resultExplicitReceiver, noExpectedType)
|
||||||
}
|
}
|
||||||
@@ -549,6 +558,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(FirContractViolation::class)
|
||||||
override fun transformAssignmentOperatorStatement(
|
override fun transformAssignmentOperatorStatement(
|
||||||
assignmentOperatorStatement: FirAssignmentOperatorStatement,
|
assignmentOperatorStatement: FirAssignmentOperatorStatement,
|
||||||
data: ResolutionMode
|
data: ResolutionMode
|
||||||
@@ -612,32 +622,18 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
expectedTypeMismatchIsReportedInChecker = true
|
expectedTypeMismatchIsReportedInChecker = true
|
||||||
)
|
)
|
||||||
dataFlowAnalyzer.exitFunctionCall(resolvedOperatorCall, callCompleted = true)
|
dataFlowAnalyzer.exitFunctionCall(resolvedOperatorCall, callCompleted = true)
|
||||||
|
|
||||||
|
val unwrappedLeftArgument = leftArgument.unwrapSmartcastExpression()
|
||||||
|
val assignmentLeftArgument = buildDesugaredAssignmentValueReferenceExpression {
|
||||||
|
expressionRef = FirExpressionRef<FirExpression>().apply { bind(unwrappedLeftArgument) }
|
||||||
|
source = leftArgument.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
|
||||||
|
}.also { storeTypeFromCallee(it) }
|
||||||
|
|
||||||
val assignment =
|
val assignment =
|
||||||
buildVariableAssignment {
|
buildVariableAssignment {
|
||||||
source = assignmentOperatorStatement.source
|
source = assignmentOperatorStatement.source
|
||||||
|
lValue = assignmentLeftArgument
|
||||||
rValue = resolvedOperatorCall
|
rValue = resolvedOperatorCall
|
||||||
calleeReference = when {
|
|
||||||
lhsIsVar -> lhsReference!!
|
|
||||||
else -> buildErrorNamedReference {
|
|
||||||
source = when (leftArgument) {
|
|
||||||
is FirFunctionCall -> leftArgument.source
|
|
||||||
is FirQualifiedAccess ->
|
|
||||||
leftArgument.calleeReference.source
|
|
||||||
else -> leftArgument.source
|
|
||||||
}
|
|
||||||
diagnostic = when {
|
|
||||||
// Use a stub diagnostic to suppress unresolved error here because it would be reported by other logic
|
|
||||||
lhsReference is FirErrorNamedReference -> ConeStubDiagnostic(ConeUnresolvedReferenceError(lhsReference.name))
|
|
||||||
lhsSymbol == null -> ConeVariableExpectedError
|
|
||||||
else -> ConeValReassignmentError(lhsSymbol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(leftArgument.unwrapSmartcastExpression() as? FirQualifiedAccess)?.let {
|
|
||||||
dispatchReceiver = it.dispatchReceiver
|
|
||||||
extensionReceiver = it.extensionReceiver
|
|
||||||
contextReceiverArguments.addAll(it.contextReceiverArguments)
|
|
||||||
}
|
|
||||||
annotations += assignmentOperatorStatement.annotations
|
annotations += assignmentOperatorStatement.annotations
|
||||||
}
|
}
|
||||||
return assignment.transform(transformer, ResolutionMode.ContextIndependent)
|
return assignment.transform(transformer, ResolutionMode.ContextIndependent)
|
||||||
@@ -863,49 +859,66 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
.also { it.resultType = booleanType }
|
.also { it.resultType = booleanType }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun transformDesugaredAssignmentValueReferenceExpression(
|
||||||
|
desugaredAssignmentValueReferenceExpression: FirDesugaredAssignmentValueReferenceExpression,
|
||||||
|
data: ResolutionMode
|
||||||
|
): FirStatement {
|
||||||
|
storeTypeFromCallee(desugaredAssignmentValueReferenceExpression)
|
||||||
|
return desugaredAssignmentValueReferenceExpression
|
||||||
|
}
|
||||||
|
|
||||||
override fun transformVariableAssignment(
|
override fun transformVariableAssignment(
|
||||||
variableAssignment: FirVariableAssignment,
|
variableAssignment: FirVariableAssignment,
|
||||||
data: ResolutionMode,
|
data: ResolutionMode,
|
||||||
): FirStatement = whileAnalysing(session, variableAssignment) {
|
): FirStatement = whileAnalysing(session, variableAssignment) {
|
||||||
// val resolvedAssignment = transformCallee(variableAssignment)
|
|
||||||
variableAssignment.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
|
variableAssignment.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
|
||||||
val resolvedAssignment = callResolver.resolveVariableAccessAndSelectCandidate(variableAssignment, isUsedAsReceiver = false)
|
|
||||||
val result = if (resolvedAssignment is FirVariableAssignment) {
|
|
||||||
val completeAssignment = callCompleter.completeCall(resolvedAssignment, noExpectedType).result // TODO: check
|
|
||||||
val resolvedReference = completeAssignment.calleeReference
|
|
||||||
if (assignAltererExtensions != null && resolvedReference is FirResolvedNamedReference) {
|
|
||||||
val alteredAssignments = assignAltererExtensions.mapNotNull { alterer ->
|
|
||||||
alterer.transformVariableAssignment(variableAssignment)?.let { it to alterer }
|
|
||||||
}
|
|
||||||
when (alteredAssignments.size) {
|
|
||||||
0 -> {}
|
|
||||||
1 -> {
|
|
||||||
val transformedAssignment = alteredAssignments.first().first
|
|
||||||
return transformedAssignment.transform(transformer, ResolutionMode.ContextIndependent)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
val isDesugaredIncrementDecrement = variableAssignment.source?.kind == KtFakeSourceElementKind.DesugaredIncrementOrDecrement
|
||||||
val altererNames = alteredAssignments.map { it.second::class.qualifiedName }
|
|
||||||
val errorReference = buildResolvedErrorReference {
|
// Expressions like `++a` are desugared into `a = a.inc()` where the LHS is a FirDesugaredAssignmentValueReferenceExpression
|
||||||
source = resolvedReference.source
|
// that's pointing to the not yet resolved `a` on the RHS. For the resolution to work, the RHS must therefore be resolved first.
|
||||||
name = resolvedReference.name
|
if (isDesugaredIncrementDecrement) {
|
||||||
resolvedSymbol = resolvedReference.resolvedSymbol
|
variableAssignment.transformRValue(transformer, ResolutionMode.ContextIndependent)
|
||||||
diagnostic = ConeAmbiguousAlteredAssign(altererNames)
|
}
|
||||||
}
|
|
||||||
completeAssignment.replaceCalleeReference(errorReference)
|
variableAssignment.transformLValue(transformer, ResolutionMode.AssignmentLValue(variableAssignment))
|
||||||
|
|
||||||
|
val resolvedReference = variableAssignment.calleeReference
|
||||||
|
|
||||||
|
if (assignAltererExtensions != null && resolvedReference is FirResolvedNamedReference) {
|
||||||
|
val alteredAssignments = assignAltererExtensions.mapNotNull { alterer ->
|
||||||
|
alterer.transformVariableAssignment(variableAssignment)?.let { it to alterer }
|
||||||
|
}
|
||||||
|
when (alteredAssignments.size) {
|
||||||
|
0 -> {}
|
||||||
|
1 -> {
|
||||||
|
val transformedAssignment = alteredAssignments.first().first
|
||||||
|
return transformedAssignment.transform(transformer, ResolutionMode.ContextIndependent)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
val extensionNames = alteredAssignments.map { it.second::class.qualifiedName }
|
||||||
|
val errorLValue = buildErrorExpression {
|
||||||
|
expression = variableAssignment.lValue
|
||||||
|
source = variableAssignment.lValue.source?.fakeElement(KtFakeSourceElementKind.AssignmentLValueError)
|
||||||
|
diagnostic = ConeAmbiguousAlteredAssign(extensionNames)
|
||||||
}
|
}
|
||||||
|
variableAssignment.replaceLValue(errorLValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
completeAssignment.transformRValue(
|
val result = if (!isDesugaredIncrementDecrement) {
|
||||||
|
variableAssignment.transformRValue(
|
||||||
transformer,
|
transformer,
|
||||||
withExpectedType(variableAssignment.lValueTypeRef, expectedTypeMismatchIsReportedInChecker = true),
|
withExpectedType(variableAssignment.lValue.typeRef, expectedTypeMismatchIsReportedInChecker = true),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// This can happen in erroneous code only
|
variableAssignment
|
||||||
resolvedAssignment
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(result as? FirVariableAssignment)?.let { dataFlowAnalyzer.exitVariableAssignment(it) }
|
(result as? FirVariableAssignment)?.let { dataFlowAnalyzer.exitVariableAssignment(it) }
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1517,12 +1530,34 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
internal fun <T> storeTypeFromCallee(access: T) where T : FirQualifiedAccess, T : FirExpression {
|
internal fun storeTypeFromCallee(access: FirQualifiedAccessExpression, isLhsOfAssignment: Boolean) {
|
||||||
val typeFromCallee = components.typeFromCallee(access)
|
val typeFromCallee = components.typeFromCallee(access)
|
||||||
access.resultType = typeFromCallee.withReplacedConeType(
|
access.resultType = typeFromCallee.withReplacedConeType(
|
||||||
session.typeApproximator.approximateToSuperType(
|
if (isLhsOfAssignment) {
|
||||||
typeFromCallee.type, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
session.typeApproximator.approximateToSubType(
|
||||||
)
|
typeFromCallee.type, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
session.typeApproximator.approximateToSuperType(
|
||||||
|
typeFromCallee.type, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun storeTypeFromCallee(expression: FirDesugaredAssignmentValueReferenceExpression) {
|
||||||
|
val referencedExpression = expression.expressionRef.value
|
||||||
|
|
||||||
|
if (referencedExpression is FirQualifiedAccessExpression) {
|
||||||
|
val typeFromCallee = components.typeFromCallee(referencedExpression)
|
||||||
|
expression.resultType = typeFromCallee.withReplacedConeType(
|
||||||
|
session.typeApproximator.approximateToSubType(
|
||||||
|
typeFromCallee.type,
|
||||||
|
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
expression.resultType = referencedExpression.resultType.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.transformers.plugin
|
package org.jetbrains.kotlin.fir.resolve.transformers.plugin
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
@@ -168,6 +169,7 @@ private class FirExpressionsResolveTransformerForSpecificAnnotations(
|
|||||||
override fun resolveQualifiedAccessAndSelectCandidate(
|
override fun resolveQualifiedAccessAndSelectCandidate(
|
||||||
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||||
isUsedAsReceiver: Boolean,
|
isUsedAsReceiver: Boolean,
|
||||||
|
callSite: FirElement,
|
||||||
): FirStatement {
|
): FirStatement {
|
||||||
return callResolver.resolveOnlyEnumOrQualifierAccessAndSelectCandidate(qualifiedAccessExpression, isUsedAsReceiver)
|
return callResolver.resolveOnlyEnumOrQualifierAccessAndSelectCandidate(qualifiedAccessExpression, isUsedAsReceiver)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.explicitReceiver
|
||||||
|
|
||||||
@OptIn(DfaInternals::class)
|
@OptIn(DfaInternals::class)
|
||||||
class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
||||||
@@ -92,7 +93,7 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getIdentifierBySymbol(flow: Flow, symbol: FirBasedSymbol<*>, fir: FirElement): Identifier {
|
private fun getIdentifierBySymbol(flow: Flow, symbol: FirBasedSymbol<*>, fir: FirElement): Identifier {
|
||||||
val expression = fir as? FirQualifiedAccess
|
val expression = fir as? FirQualifiedAccessExpression ?: (fir as? FirVariableAssignment)?.lValue as? FirQualifiedAccessExpression
|
||||||
// TODO: don't create receiver variables if not going to create the composed variable either?
|
// TODO: don't create receiver variables if not going to create the composed variable either?
|
||||||
return Identifier(
|
return Identifier(
|
||||||
symbol,
|
symbol,
|
||||||
@@ -104,10 +105,10 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
|||||||
private fun createReal(flow: Flow, identifier: Identifier, originalFir: FirElement, stability: PropertyStability): RealVariable {
|
private fun createReal(flow: Flow, identifier: Identifier, originalFir: FirElement, stability: PropertyStability): RealVariable {
|
||||||
val receiver: FirExpression?
|
val receiver: FirExpression?
|
||||||
val isThisReference: Boolean
|
val isThisReference: Boolean
|
||||||
val expression: FirQualifiedAccess? = when (originalFir) {
|
val expression: FirQualifiedAccessExpression? = when (originalFir) {
|
||||||
is FirQualifiedAccessExpression -> originalFir
|
is FirQualifiedAccessExpression -> originalFir
|
||||||
is FirWhenSubjectExpression -> originalFir.whenRef.value.subject as? FirQualifiedAccessExpression
|
is FirWhenSubjectExpression -> originalFir.whenRef.value.subject as? FirQualifiedAccessExpression
|
||||||
is FirVariableAssignment -> originalFir
|
is FirVariableAssignment -> originalFir.unwrapLValue()
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +163,7 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
|||||||
property.receiverParameter != null -> PropertyStability.PROPERTY_WITH_GETTER
|
property.receiverParameter != null -> PropertyStability.PROPERTY_WITH_GETTER
|
||||||
property.getter.let { it != null && it !is FirDefaultPropertyAccessor } -> PropertyStability.PROPERTY_WITH_GETTER
|
property.getter.let { it != null && it !is FirDefaultPropertyAccessor } -> PropertyStability.PROPERTY_WITH_GETTER
|
||||||
property.modality != Modality.FINAL -> {
|
property.modality != Modality.FINAL -> {
|
||||||
val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccess)?.dispatchReceiver ?: return null
|
val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccessExpression)?.dispatchReceiver ?: return null
|
||||||
val receiverType = dispatchReceiver.typeRef.coneTypeSafe<ConeClassLikeType>()?.fullyExpandedType(session) ?: return null
|
val receiverType = dispatchReceiver.typeRef.coneTypeSafe<ConeClassLikeType>()?.fullyExpandedType(session) ?: return null
|
||||||
val receiverSymbol = receiverType.lookupTag.toSymbol(session) ?: return null
|
val receiverSymbol = receiverType.lookupTag.toSymbol(session) ?: return null
|
||||||
when (val receiverFir = receiverSymbol.fir) {
|
when (val receiverFir = receiverSymbol.fir) {
|
||||||
|
|||||||
+2
-4
@@ -5,9 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.dfa.cfg
|
package org.jetbrains.kotlin.fir.resolve.dfa.cfg
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirDoWhileLoop
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirLoop
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
|
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.renderer.FirCallNoArgumentsRenderer
|
import org.jetbrains.kotlin.fir.renderer.FirCallNoArgumentsRenderer
|
||||||
@@ -55,7 +53,7 @@ fun CFGNode<*>.render(): String =
|
|||||||
CfgRenderer.renderAsCallableDeclarationString(fir)
|
CfgRenderer.renderAsCallableDeclarationString(fir)
|
||||||
}"
|
}"
|
||||||
|
|
||||||
is VariableAssignmentNode -> "Assignment: ${CfgRenderer.renderElementAsString(fir.lValue)}"
|
is VariableAssignmentNode -> "Assignment: ${fir.calleeReference?.let(CfgRenderer::renderElementAsString)}"
|
||||||
is FunctionCallNode -> "Function call: ${CfgRenderer.renderElementAsString(fir)}"
|
is FunctionCallNode -> "Function call: ${CfgRenderer.renderElementAsString(fir)}"
|
||||||
is DelegatedConstructorCallNode -> "Delegated constructor call: ${CfgRenderer.renderElementAsString(fir)}"
|
is DelegatedConstructorCallNode -> "Delegated constructor call: ${CfgRenderer.renderElementAsString(fir)}"
|
||||||
is StringConcatenationCallNode -> "String concatenation call: ${CfgRenderer.renderElementAsString(fir)}"
|
is StringConcatenationCallNode -> "String concatenation call: ${CfgRenderer.renderElementAsString(fir)}"
|
||||||
|
|||||||
@@ -40,10 +40,12 @@ val FirExpression.coneType: ConeKotlinType
|
|||||||
val FirElement.symbol: FirBasedSymbol<*>?
|
val FirElement.symbol: FirBasedSymbol<*>?
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
is FirResolvable -> symbol
|
is FirResolvable -> symbol
|
||||||
|
is FirVariableAssignment -> unwrapLValue()?.symbol
|
||||||
is FirDeclaration -> symbol
|
is FirDeclaration -> symbol
|
||||||
is FirWhenSubjectExpression -> whenRef.value.subject?.symbol
|
is FirWhenSubjectExpression -> whenRef.value.subject?.symbol
|
||||||
is FirSafeCallExpression -> selector.symbol
|
is FirSafeCallExpression -> selector.symbol
|
||||||
is FirSmartCastExpression -> originalExpression.symbol
|
is FirSmartCastExpression -> originalExpression.symbol
|
||||||
|
is FirDesugaredAssignmentValueReferenceExpression -> expressionRef.value.symbol
|
||||||
else -> null
|
else -> null
|
||||||
}?.takeIf {
|
}?.takeIf {
|
||||||
(this as? FirExpression)?.unwrapSmartcastExpression() is FirThisReceiverExpression ||
|
(this as? FirExpression)?.unwrapSmartcastExpression() is FirThisReceiverExpression ||
|
||||||
|
|||||||
-4
@@ -138,10 +138,6 @@ object ConeVariableExpectedError : ConeDiagnostic {
|
|||||||
override val reason: String get() = "Variable expected"
|
override val reason: String get() = "Variable expected"
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConeValReassignmentError(val variable: FirVariableSymbol<*>) : ConeDiagnostic {
|
|
||||||
override val reason: String get() = "Re-assigning a val variable"
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConeContractDescriptionError(override val reason: String) : ConeDiagnostic
|
class ConeContractDescriptionError(override val reason: String) : ConeDiagnostic
|
||||||
|
|
||||||
class ConeIllegalAnnotationError(val name: Name) : ConeDiagnostic {
|
class ConeIllegalAnnotationError(val name: Name) : ConeDiagnostic {
|
||||||
|
|||||||
+4
-4
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirCallableReferenceAccess : FirQualifiedAccessExpression() {
|
abstract class FirCallableReferenceAccess : FirQualifiedAccessExpression() {
|
||||||
abstract override val source: KtSourceElement?
|
|
||||||
abstract override val typeRef: FirTypeRef
|
abstract override val typeRef: FirTypeRef
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract override val contextReceiverArguments: List<FirExpression>
|
abstract override val contextReceiverArguments: List<FirExpression>
|
||||||
@@ -28,6 +27,7 @@ abstract class FirCallableReferenceAccess : FirQualifiedAccessExpression() {
|
|||||||
abstract override val explicitReceiver: FirExpression?
|
abstract override val explicitReceiver: FirExpression?
|
||||||
abstract override val dispatchReceiver: FirExpression
|
abstract override val dispatchReceiver: FirExpression
|
||||||
abstract override val extensionReceiver: FirExpression
|
abstract override val extensionReceiver: FirExpression
|
||||||
|
abstract override val source: KtSourceElement?
|
||||||
abstract override val calleeReference: FirNamedReference
|
abstract override val calleeReference: FirNamedReference
|
||||||
abstract val hasQuestionMarkAtLHS: Boolean
|
abstract val hasQuestionMarkAtLHS: Boolean
|
||||||
|
|
||||||
@@ -37,9 +37,6 @@ abstract class FirCallableReferenceAccess : FirQualifiedAccessExpression() {
|
|||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
transformer.transformCallableReferenceAccess(this, data) as E
|
transformer.transformCallableReferenceAccess(this, data) as E
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
abstract override fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
@@ -54,6 +51,9 @@ abstract class FirCallableReferenceAccess : FirQualifiedAccessExpression() {
|
|||||||
|
|
||||||
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
||||||
|
|
||||||
|
@FirImplementationDetail
|
||||||
|
abstract override fun replaceSource(newSource: KtSourceElement?)
|
||||||
|
|
||||||
abstract fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
abstract fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
||||||
|
|
||||||
abstract override fun replaceCalleeReference(newCalleeReference: FirReference)
|
abstract override fun replaceCalleeReference(newCalleeReference: FirReference)
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirComponentCall : FirFunctionCall() {
|
abstract class FirComponentCall : FirFunctionCall() {
|
||||||
abstract override val source: KtSourceElement?
|
|
||||||
abstract override val typeRef: FirTypeRef
|
abstract override val typeRef: FirTypeRef
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract override val contextReceiverArguments: List<FirExpression>
|
abstract override val contextReceiverArguments: List<FirExpression>
|
||||||
abstract override val typeArguments: List<FirTypeProjection>
|
abstract override val typeArguments: List<FirTypeProjection>
|
||||||
abstract override val dispatchReceiver: FirExpression
|
abstract override val dispatchReceiver: FirExpression
|
||||||
abstract override val extensionReceiver: FirExpression
|
abstract override val extensionReceiver: FirExpression
|
||||||
|
abstract override val source: KtSourceElement?
|
||||||
abstract override val argumentList: FirArgumentList
|
abstract override val argumentList: FirArgumentList
|
||||||
abstract override val calleeReference: FirNamedReference
|
abstract override val calleeReference: FirNamedReference
|
||||||
abstract override val origin: FirFunctionCallOrigin
|
abstract override val origin: FirFunctionCallOrigin
|
||||||
@@ -39,9 +39,6 @@ abstract class FirComponentCall : FirFunctionCall() {
|
|||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
transformer.transformComponentCall(this, data) as E
|
transformer.transformComponentCall(this, data) as E
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
abstract override fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
@@ -54,6 +51,9 @@ abstract class FirComponentCall : FirFunctionCall() {
|
|||||||
|
|
||||||
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
||||||
|
|
||||||
|
@FirImplementationDetail
|
||||||
|
abstract override fun replaceSource(newSource: KtSourceElement?)
|
||||||
|
|
||||||
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
|
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
|
||||||
|
|
||||||
abstract override fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
abstract override fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.KtSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirExpressionRef
|
||||||
|
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 FirDesugaredAssignmentValueReferenceExpression : FirExpression() {
|
||||||
|
abstract override val source: KtSourceElement?
|
||||||
|
abstract override val typeRef: FirTypeRef
|
||||||
|
abstract override val annotations: List<FirAnnotation>
|
||||||
|
abstract val expressionRef: FirExpressionRef<FirExpression>
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitDesugaredAssignmentValueReferenceExpression(this, data)
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
|
transformer.transformDesugaredAssignmentValueReferenceExpression(this, data) as E
|
||||||
|
|
||||||
|
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||||
|
|
||||||
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
|
|
||||||
|
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirDesugaredAssignmentValueReferenceExpression
|
||||||
|
}
|
||||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirFunctionCall : FirQualifiedAccessExpression(), FirCall {
|
abstract class FirFunctionCall : FirQualifiedAccessExpression(), FirCall {
|
||||||
abstract override val source: KtSourceElement?
|
|
||||||
abstract override val typeRef: FirTypeRef
|
abstract override val typeRef: FirTypeRef
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract override val contextReceiverArguments: List<FirExpression>
|
abstract override val contextReceiverArguments: List<FirExpression>
|
||||||
@@ -28,6 +27,7 @@ abstract class FirFunctionCall : FirQualifiedAccessExpression(), FirCall {
|
|||||||
abstract override val explicitReceiver: FirExpression?
|
abstract override val explicitReceiver: FirExpression?
|
||||||
abstract override val dispatchReceiver: FirExpression
|
abstract override val dispatchReceiver: FirExpression
|
||||||
abstract override val extensionReceiver: FirExpression
|
abstract override val extensionReceiver: FirExpression
|
||||||
|
abstract override val source: KtSourceElement?
|
||||||
abstract override val argumentList: FirArgumentList
|
abstract override val argumentList: FirArgumentList
|
||||||
abstract override val calleeReference: FirNamedReference
|
abstract override val calleeReference: FirNamedReference
|
||||||
abstract val origin: FirFunctionCallOrigin
|
abstract val origin: FirFunctionCallOrigin
|
||||||
@@ -38,9 +38,6 @@ abstract class FirFunctionCall : FirQualifiedAccessExpression(), FirCall {
|
|||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
transformer.transformFunctionCall(this, data) as E
|
transformer.transformFunctionCall(this, data) as E
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
abstract override fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
@@ -55,6 +52,9 @@ abstract class FirFunctionCall : FirQualifiedAccessExpression(), FirCall {
|
|||||||
|
|
||||||
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
||||||
|
|
||||||
|
@FirImplementationDetail
|
||||||
|
abstract override fun replaceSource(newSource: KtSourceElement?)
|
||||||
|
|
||||||
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
|
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
|
||||||
|
|
||||||
abstract fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
abstract fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirImplicitInvokeCall : FirFunctionCall() {
|
abstract class FirImplicitInvokeCall : FirFunctionCall() {
|
||||||
abstract override val source: KtSourceElement?
|
|
||||||
abstract override val typeRef: FirTypeRef
|
abstract override val typeRef: FirTypeRef
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract override val contextReceiverArguments: List<FirExpression>
|
abstract override val contextReceiverArguments: List<FirExpression>
|
||||||
@@ -28,6 +27,7 @@ abstract class FirImplicitInvokeCall : FirFunctionCall() {
|
|||||||
abstract override val explicitReceiver: FirExpression?
|
abstract override val explicitReceiver: FirExpression?
|
||||||
abstract override val dispatchReceiver: FirExpression
|
abstract override val dispatchReceiver: FirExpression
|
||||||
abstract override val extensionReceiver: FirExpression
|
abstract override val extensionReceiver: FirExpression
|
||||||
|
abstract override val source: KtSourceElement?
|
||||||
abstract override val argumentList: FirArgumentList
|
abstract override val argumentList: FirArgumentList
|
||||||
abstract override val calleeReference: FirNamedReference
|
abstract override val calleeReference: FirNamedReference
|
||||||
abstract override val origin: FirFunctionCallOrigin
|
abstract override val origin: FirFunctionCallOrigin
|
||||||
@@ -38,9 +38,6 @@ abstract class FirImplicitInvokeCall : FirFunctionCall() {
|
|||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
transformer.transformImplicitInvokeCall(this, data) as E
|
transformer.transformImplicitInvokeCall(this, data) as E
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
abstract override fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
@@ -55,6 +52,9 @@ abstract class FirImplicitInvokeCall : FirFunctionCall() {
|
|||||||
|
|
||||||
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
||||||
|
|
||||||
|
@FirImplementationDetail
|
||||||
|
abstract override fun replaceSource(newSource: KtSourceElement?)
|
||||||
|
|
||||||
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
|
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
|
||||||
|
|
||||||
abstract override fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
abstract override fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
||||||
|
|||||||
+4
-4
@@ -20,12 +20,12 @@ import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirIntegerLiteralOperatorCall : FirFunctionCall() {
|
abstract class FirIntegerLiteralOperatorCall : FirFunctionCall() {
|
||||||
abstract override val source: KtSourceElement?
|
|
||||||
abstract override val typeRef: FirTypeRef
|
abstract override val typeRef: FirTypeRef
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract override val contextReceiverArguments: List<FirExpression>
|
abstract override val contextReceiverArguments: List<FirExpression>
|
||||||
abstract override val typeArguments: List<FirTypeProjection>
|
abstract override val typeArguments: List<FirTypeProjection>
|
||||||
abstract override val explicitReceiver: FirExpression?
|
abstract override val explicitReceiver: FirExpression?
|
||||||
|
abstract override val source: KtSourceElement?
|
||||||
abstract override val argumentList: FirArgumentList
|
abstract override val argumentList: FirArgumentList
|
||||||
abstract override val calleeReference: FirNamedReference
|
abstract override val calleeReference: FirNamedReference
|
||||||
abstract override val origin: FirFunctionCallOrigin
|
abstract override val origin: FirFunctionCallOrigin
|
||||||
@@ -38,9 +38,6 @@ abstract class FirIntegerLiteralOperatorCall : FirFunctionCall() {
|
|||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
transformer.transformIntegerLiteralOperatorCall(this, data) as E
|
transformer.transformIntegerLiteralOperatorCall(this, data) as E
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
abstract override fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
@@ -51,6 +48,9 @@ abstract class FirIntegerLiteralOperatorCall : FirFunctionCall() {
|
|||||||
|
|
||||||
abstract override fun replaceExplicitReceiver(newExplicitReceiver: FirExpression?)
|
abstract override fun replaceExplicitReceiver(newExplicitReceiver: FirExpression?)
|
||||||
|
|
||||||
|
@FirImplementationDetail
|
||||||
|
abstract override fun replaceSource(newSource: KtSourceElement?)
|
||||||
|
|
||||||
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
|
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
|
||||||
|
|
||||||
abstract override fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
abstract override fun replaceCalleeReference(newCalleeReference: FirNamedReference)
|
||||||
|
|||||||
+4
-4
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirPropertyAccessExpression : FirQualifiedAccessExpression() {
|
abstract class FirPropertyAccessExpression : FirQualifiedAccessExpression() {
|
||||||
abstract override val source: KtSourceElement?
|
|
||||||
abstract override val typeRef: FirTypeRef
|
abstract override val typeRef: FirTypeRef
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract override val calleeReference: FirReference
|
abstract override val calleeReference: FirReference
|
||||||
@@ -29,6 +28,7 @@ abstract class FirPropertyAccessExpression : FirQualifiedAccessExpression() {
|
|||||||
abstract override val explicitReceiver: FirExpression?
|
abstract override val explicitReceiver: FirExpression?
|
||||||
abstract override val dispatchReceiver: FirExpression
|
abstract override val dispatchReceiver: FirExpression
|
||||||
abstract override val extensionReceiver: FirExpression
|
abstract override val extensionReceiver: FirExpression
|
||||||
|
abstract override val source: KtSourceElement?
|
||||||
abstract val nonFatalDiagnostics: List<ConeDiagnostic>
|
abstract val nonFatalDiagnostics: List<ConeDiagnostic>
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitPropertyAccessExpression(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitPropertyAccessExpression(this, data)
|
||||||
@@ -37,9 +37,6 @@ abstract class FirPropertyAccessExpression : FirQualifiedAccessExpression() {
|
|||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
transformer.transformPropertyAccessExpression(this, data) as E
|
transformer.transformPropertyAccessExpression(this, data) as E
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
abstract override fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
@@ -56,6 +53,9 @@ abstract class FirPropertyAccessExpression : FirQualifiedAccessExpression() {
|
|||||||
|
|
||||||
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
||||||
|
|
||||||
|
@FirImplementationDetail
|
||||||
|
abstract override fun replaceSource(newSource: KtSourceElement?)
|
||||||
|
|
||||||
abstract fun replaceNonFatalDiagnostics(newNonFatalDiagnostics: List<ConeDiagnostic>)
|
abstract fun replaceNonFatalDiagnostics(newNonFatalDiagnostics: List<ConeDiagnostic>)
|
||||||
|
|
||||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirPropertyAccessExpression
|
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirPropertyAccessExpression
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2023 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.KtSourceElement
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.*
|
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file was generated automatically
|
|
||||||
* DO NOT MODIFY IT MANUALLY
|
|
||||||
*/
|
|
||||||
|
|
||||||
interface FirQualifiedAccess : FirResolvable, FirStatement, FirContextReceiverArgumentListOwner {
|
|
||||||
override val calleeReference: FirReference
|
|
||||||
override val annotations: List<FirAnnotation>
|
|
||||||
override val contextReceiverArguments: List<FirExpression>
|
|
||||||
val typeArguments: List<FirTypeProjection>
|
|
||||||
val explicitReceiver: FirExpression?
|
|
||||||
val dispatchReceiver: FirExpression
|
|
||||||
val extensionReceiver: FirExpression
|
|
||||||
override val source: KtSourceElement?
|
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitQualifiedAccess(this, data)
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
|
||||||
transformer.transformQualifiedAccess(this, data) as E
|
|
||||||
|
|
||||||
override fun replaceCalleeReference(newCalleeReference: FirReference)
|
|
||||||
|
|
||||||
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
|
||||||
|
|
||||||
override fun replaceContextReceiverArguments(newContextReceiverArguments: List<FirExpression>)
|
|
||||||
|
|
||||||
fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
|
|
||||||
|
|
||||||
fun replaceExplicitReceiver(newExplicitReceiver: FirExpression?)
|
|
||||||
|
|
||||||
fun replaceDispatchReceiver(newDispatchReceiver: FirExpression)
|
|
||||||
|
|
||||||
fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirQualifiedAccess
|
|
||||||
|
|
||||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirQualifiedAccess
|
|
||||||
|
|
||||||
fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirQualifiedAccess
|
|
||||||
|
|
||||||
fun <D> transformExplicitReceiver(transformer: FirTransformer<D>, data: D): FirQualifiedAccess
|
|
||||||
}
|
|
||||||
+15
-15
@@ -18,16 +18,16 @@ import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|||||||
* DO NOT MODIFY IT MANUALLY
|
* DO NOT MODIFY IT MANUALLY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirQualifiedAccessExpression : FirExpression(), FirQualifiedAccess {
|
abstract class FirQualifiedAccessExpression : FirExpression(), FirResolvable, FirContextReceiverArgumentListOwner {
|
||||||
abstract override val source: KtSourceElement?
|
|
||||||
abstract override val typeRef: FirTypeRef
|
abstract override val typeRef: FirTypeRef
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract override val calleeReference: FirReference
|
abstract override val calleeReference: FirReference
|
||||||
abstract override val contextReceiverArguments: List<FirExpression>
|
abstract override val contextReceiverArguments: List<FirExpression>
|
||||||
abstract override val typeArguments: List<FirTypeProjection>
|
abstract val typeArguments: List<FirTypeProjection>
|
||||||
abstract override val explicitReceiver: FirExpression?
|
abstract val explicitReceiver: FirExpression?
|
||||||
abstract override val dispatchReceiver: FirExpression
|
abstract val dispatchReceiver: FirExpression
|
||||||
abstract override val extensionReceiver: FirExpression
|
abstract val extensionReceiver: FirExpression
|
||||||
|
abstract override val source: KtSourceElement?
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitQualifiedAccessExpression(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitQualifiedAccessExpression(this, data)
|
||||||
|
|
||||||
@@ -35,9 +35,6 @@ abstract class FirQualifiedAccessExpression : FirExpression(), FirQualifiedAcces
|
|||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
transformer.transformQualifiedAccessExpression(this, data) as E
|
transformer.transformQualifiedAccessExpression(this, data) as E
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
abstract override fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
@@ -46,19 +43,22 @@ abstract class FirQualifiedAccessExpression : FirExpression(), FirQualifiedAcces
|
|||||||
|
|
||||||
abstract override fun replaceContextReceiverArguments(newContextReceiverArguments: List<FirExpression>)
|
abstract override fun replaceContextReceiverArguments(newContextReceiverArguments: List<FirExpression>)
|
||||||
|
|
||||||
abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
|
abstract fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
|
||||||
|
|
||||||
abstract override fun replaceExplicitReceiver(newExplicitReceiver: FirExpression?)
|
abstract fun replaceExplicitReceiver(newExplicitReceiver: FirExpression?)
|
||||||
|
|
||||||
abstract override fun replaceDispatchReceiver(newDispatchReceiver: FirExpression)
|
abstract fun replaceDispatchReceiver(newDispatchReceiver: FirExpression)
|
||||||
|
|
||||||
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
abstract fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
||||||
|
|
||||||
|
@FirImplementationDetail
|
||||||
|
abstract fun replaceSource(newSource: KtSourceElement?)
|
||||||
|
|
||||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirQualifiedAccessExpression
|
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirQualifiedAccessExpression
|
||||||
|
|
||||||
abstract override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirQualifiedAccessExpression
|
abstract override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirQualifiedAccessExpression
|
||||||
|
|
||||||
abstract override fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirQualifiedAccessExpression
|
abstract fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirQualifiedAccessExpression
|
||||||
|
|
||||||
abstract override fun <D> transformExplicitReceiver(transformer: FirTransformer<D>, data: D): FirQualifiedAccessExpression
|
abstract fun <D> transformExplicitReceiver(transformer: FirTransformer<D>, data: D): FirQualifiedAccessExpression
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirThisReceiverExpression : FirQualifiedAccessExpression() {
|
abstract class FirThisReceiverExpression : FirQualifiedAccessExpression() {
|
||||||
abstract override val source: KtSourceElement?
|
|
||||||
abstract override val typeRef: FirTypeRef
|
abstract override val typeRef: FirTypeRef
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract override val contextReceiverArguments: List<FirExpression>
|
abstract override val contextReceiverArguments: List<FirExpression>
|
||||||
@@ -28,6 +27,7 @@ abstract class FirThisReceiverExpression : FirQualifiedAccessExpression() {
|
|||||||
abstract override val explicitReceiver: FirExpression?
|
abstract override val explicitReceiver: FirExpression?
|
||||||
abstract override val dispatchReceiver: FirExpression
|
abstract override val dispatchReceiver: FirExpression
|
||||||
abstract override val extensionReceiver: FirExpression
|
abstract override val extensionReceiver: FirExpression
|
||||||
|
abstract override val source: KtSourceElement?
|
||||||
abstract override val calleeReference: FirThisReference
|
abstract override val calleeReference: FirThisReference
|
||||||
abstract val isImplicit: Boolean
|
abstract val isImplicit: Boolean
|
||||||
|
|
||||||
@@ -37,9 +37,6 @@ abstract class FirThisReceiverExpression : FirQualifiedAccessExpression() {
|
|||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
transformer.transformThisReceiverExpression(this, data) as E
|
transformer.transformThisReceiverExpression(this, data) as E
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
abstract override fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
@@ -54,6 +51,9 @@ abstract class FirThisReceiverExpression : FirQualifiedAccessExpression() {
|
|||||||
|
|
||||||
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
||||||
|
|
||||||
|
@FirImplementationDetail
|
||||||
|
abstract override fun replaceSource(newSource: KtSourceElement?)
|
||||||
|
|
||||||
abstract fun replaceCalleeReference(newCalleeReference: FirThisReference)
|
abstract fun replaceCalleeReference(newCalleeReference: FirThisReference)
|
||||||
|
|
||||||
abstract override fun replaceCalleeReference(newCalleeReference: FirReference)
|
abstract override fun replaceCalleeReference(newCalleeReference: FirReference)
|
||||||
|
|||||||
+5
-35
@@ -8,28 +8,17 @@ package org.jetbrains.kotlin.fir.expressions
|
|||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirPureAbstractElement
|
import org.jetbrains.kotlin.fir.FirPureAbstractElement
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.*
|
import org.jetbrains.kotlin.fir.visitors.*
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file was generated automatically
|
* This file was generated automatically
|
||||||
* DO NOT MODIFY IT MANUALLY
|
* DO NOT MODIFY IT MANUALLY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirVariableAssignment : FirPureAbstractElement(), FirQualifiedAccess {
|
abstract class FirVariableAssignment : FirPureAbstractElement(), FirStatement {
|
||||||
abstract override val calleeReference: FirReference
|
|
||||||
abstract override val annotations: List<FirAnnotation>
|
|
||||||
abstract override val contextReceiverArguments: List<FirExpression>
|
|
||||||
abstract override val typeArguments: List<FirTypeProjection>
|
|
||||||
abstract override val explicitReceiver: FirExpression?
|
|
||||||
abstract override val dispatchReceiver: FirExpression
|
|
||||||
abstract override val extensionReceiver: FirExpression
|
|
||||||
abstract override val source: KtSourceElement?
|
abstract override val source: KtSourceElement?
|
||||||
abstract val lValue: FirReference
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract val lValueTypeRef: FirTypeRef
|
abstract val lValue: FirExpression
|
||||||
abstract val rValue: FirExpression
|
abstract val rValue: FirExpression
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitVariableAssignment(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitVariableAssignment(this, data)
|
||||||
@@ -38,32 +27,13 @@ abstract class FirVariableAssignment : FirPureAbstractElement(), FirQualifiedAcc
|
|||||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||||
transformer.transformVariableAssignment(this, data) as E
|
transformer.transformVariableAssignment(this, data) as E
|
||||||
|
|
||||||
abstract override fun replaceCalleeReference(newCalleeReference: FirReference)
|
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
|
|
||||||
abstract override fun replaceContextReceiverArguments(newContextReceiverArguments: List<FirExpression>)
|
abstract fun replaceLValue(newLValue: FirExpression)
|
||||||
|
|
||||||
abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
|
|
||||||
|
|
||||||
abstract override fun replaceExplicitReceiver(newExplicitReceiver: FirExpression?)
|
|
||||||
|
|
||||||
abstract override fun replaceDispatchReceiver(newDispatchReceiver: FirExpression)
|
|
||||||
|
|
||||||
abstract override fun replaceExtensionReceiver(newExtensionReceiver: FirExpression)
|
|
||||||
|
|
||||||
@FirImplementationDetail
|
|
||||||
abstract override fun replaceSource(newSource: KtSourceElement?)
|
|
||||||
|
|
||||||
abstract fun replaceLValueTypeRef(newLValueTypeRef: FirTypeRef)
|
|
||||||
|
|
||||||
abstract override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirVariableAssignment
|
|
||||||
|
|
||||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirVariableAssignment
|
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirVariableAssignment
|
||||||
|
|
||||||
abstract override fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirVariableAssignment
|
abstract fun <D> transformLValue(transformer: FirTransformer<D>, data: D): FirVariableAssignment
|
||||||
|
|
||||||
abstract override fun <D> transformExplicitReceiver(transformer: FirTransformer<D>, data: D): FirVariableAssignment
|
|
||||||
|
|
||||||
abstract fun <D> transformRValue(transformer: FirTransformer<D>, data: D): FirVariableAssignment
|
abstract fun <D> transformRValue(transformer: FirTransformer<D>, data: D): FirVariableAssignment
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.FirCallBuilder
|
import org.jetbrains.kotlin.fir.expressions.builder.FirCallBuilder
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessBuilder
|
import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessExpressionBuilder
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
@@ -27,7 +27,8 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
interface FirAbstractFunctionCallBuilder : FirQualifiedAccessBuilder, FirCallBuilder {
|
interface FirAbstractFunctionCallBuilder : FirQualifiedAccessExpressionBuilder, FirCallBuilder {
|
||||||
|
abstract override var typeRef: FirTypeRef
|
||||||
abstract override val annotations: MutableList<FirAnnotation>
|
abstract override val annotations: MutableList<FirAnnotation>
|
||||||
abstract override val contextReceiverArguments: MutableList<FirExpression>
|
abstract override val contextReceiverArguments: MutableList<FirExpression>
|
||||||
abstract override val typeArguments: MutableList<FirTypeProjection>
|
abstract override val typeArguments: MutableList<FirTypeProjection>
|
||||||
@@ -36,7 +37,6 @@ interface FirAbstractFunctionCallBuilder : FirQualifiedAccessBuilder, FirCallBui
|
|||||||
abstract override var extensionReceiver: FirExpression
|
abstract override var extensionReceiver: FirExpression
|
||||||
abstract override var source: KtSourceElement?
|
abstract override var source: KtSourceElement?
|
||||||
abstract override var argumentList: FirArgumentList
|
abstract override var argumentList: FirArgumentList
|
||||||
abstract var typeRef: FirTypeRef
|
|
||||||
abstract var calleeReference: FirNamedReference
|
abstract var calleeReference: FirNamedReference
|
||||||
abstract var origin: FirFunctionCallOrigin
|
abstract var origin: FirFunctionCallOrigin
|
||||||
override fun build(): FirFunctionCall
|
override fun build(): FirFunctionCall
|
||||||
|
|||||||
+4
-4
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
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.FirQualifiedAccessExpressionBuilder
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirCallableReferenceAccessImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirCallableReferenceAccessImpl
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
@@ -33,8 +33,7 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
class FirCallableReferenceAccessBuilder : FirQualifiedAccessBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
class FirCallableReferenceAccessBuilder : FirQualifiedAccessExpressionBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||||
override var source: KtSourceElement? = null
|
|
||||||
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
||||||
@@ -42,12 +41,12 @@ class FirCallableReferenceAccessBuilder : FirQualifiedAccessBuilder, FirAnnotati
|
|||||||
override var explicitReceiver: FirExpression? = null
|
override var explicitReceiver: FirExpression? = null
|
||||||
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
||||||
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
||||||
|
override var source: KtSourceElement? = null
|
||||||
lateinit var calleeReference: FirNamedReference
|
lateinit var calleeReference: FirNamedReference
|
||||||
var hasQuestionMarkAtLHS: Boolean = false
|
var hasQuestionMarkAtLHS: Boolean = false
|
||||||
|
|
||||||
override fun build(): FirCallableReferenceAccess {
|
override fun build(): FirCallableReferenceAccess {
|
||||||
return FirCallableReferenceAccessImpl(
|
return FirCallableReferenceAccessImpl(
|
||||||
source,
|
|
||||||
typeRef,
|
typeRef,
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
contextReceiverArguments.toMutableOrEmpty(),
|
contextReceiverArguments.toMutableOrEmpty(),
|
||||||
@@ -55,6 +54,7 @@ class FirCallableReferenceAccessBuilder : FirQualifiedAccessBuilder, FirAnnotati
|
|||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
dispatchReceiver,
|
dispatchReceiver,
|
||||||
extensionReceiver,
|
extensionReceiver,
|
||||||
|
source,
|
||||||
calleeReference,
|
calleeReference,
|
||||||
hasQuestionMarkAtLHS,
|
hasQuestionMarkAtLHS,
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-2
@@ -39,24 +39,24 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
class FirComponentCallBuilder : FirCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
class FirComponentCallBuilder : FirCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||||
override var source: KtSourceElement? = null
|
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
||||||
val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
|
val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
|
||||||
var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
||||||
var extensionReceiver: FirExpression = FirNoReceiverExpression
|
var extensionReceiver: FirExpression = FirNoReceiverExpression
|
||||||
|
override var source: KtSourceElement? = null
|
||||||
override var argumentList: FirArgumentList = FirEmptyArgumentList
|
override var argumentList: FirArgumentList = FirEmptyArgumentList
|
||||||
lateinit var explicitReceiver: FirExpression
|
lateinit var explicitReceiver: FirExpression
|
||||||
var componentIndex: Int by kotlin.properties.Delegates.notNull<Int>()
|
var componentIndex: Int by kotlin.properties.Delegates.notNull<Int>()
|
||||||
|
|
||||||
override fun build(): FirComponentCall {
|
override fun build(): FirComponentCall {
|
||||||
return FirComponentCallImpl(
|
return FirComponentCallImpl(
|
||||||
source,
|
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
contextReceiverArguments.toMutableOrEmpty(),
|
contextReceiverArguments.toMutableOrEmpty(),
|
||||||
typeArguments.toMutableOrEmpty(),
|
typeArguments.toMutableOrEmpty(),
|
||||||
dispatchReceiver,
|
dispatchReceiver,
|
||||||
extensionReceiver,
|
extensionReceiver,
|
||||||
|
source,
|
||||||
argumentList,
|
argumentList,
|
||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
componentIndex,
|
componentIndex,
|
||||||
|
|||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("DuplicatedCode")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.expressions.builder
|
||||||
|
|
||||||
|
import kotlin.contracts.*
|
||||||
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirExpressionRef
|
||||||
|
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
|
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirDesugaredAssignmentValueReferenceExpressionImpl
|
||||||
|
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 FirDesugaredAssignmentValueReferenceExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||||
|
override var source: KtSourceElement? = null
|
||||||
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
|
lateinit var expressionRef: FirExpressionRef<FirExpression>
|
||||||
|
|
||||||
|
override fun build(): FirDesugaredAssignmentValueReferenceExpression {
|
||||||
|
return FirDesugaredAssignmentValueReferenceExpressionImpl(
|
||||||
|
source,
|
||||||
|
annotations.toMutableOrEmpty(),
|
||||||
|
expressionRef,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated("Modification of 'typeRef' has no impact for FirDesugaredAssignmentValueReferenceExpressionBuilder", level = DeprecationLevel.HIDDEN)
|
||||||
|
override var typeRef: FirTypeRef
|
||||||
|
get() = throw IllegalStateException()
|
||||||
|
set(_) {
|
||||||
|
throw IllegalStateException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
inline fun buildDesugaredAssignmentValueReferenceExpression(init: FirDesugaredAssignmentValueReferenceExpressionBuilder.() -> Unit): FirDesugaredAssignmentValueReferenceExpression {
|
||||||
|
contract {
|
||||||
|
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return FirDesugaredAssignmentValueReferenceExpressionBuilder().apply(init).build()
|
||||||
|
}
|
||||||
+2
-2
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
open class FirFunctionCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
open class FirFunctionCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||||
override var source: KtSourceElement? = null
|
|
||||||
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
||||||
@@ -45,6 +44,7 @@ open class FirFunctionCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotatio
|
|||||||
override var explicitReceiver: FirExpression? = null
|
override var explicitReceiver: FirExpression? = null
|
||||||
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
||||||
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
||||||
|
override var source: KtSourceElement? = null
|
||||||
override var argumentList: FirArgumentList = FirEmptyArgumentList
|
override var argumentList: FirArgumentList = FirEmptyArgumentList
|
||||||
override lateinit var calleeReference: FirNamedReference
|
override lateinit var calleeReference: FirNamedReference
|
||||||
override var origin: FirFunctionCallOrigin = FirFunctionCallOrigin.Regular
|
override var origin: FirFunctionCallOrigin = FirFunctionCallOrigin.Regular
|
||||||
@@ -52,7 +52,6 @@ open class FirFunctionCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotatio
|
|||||||
@OptIn(FirImplementationDetail::class)
|
@OptIn(FirImplementationDetail::class)
|
||||||
override fun build(): FirFunctionCall {
|
override fun build(): FirFunctionCall {
|
||||||
return FirFunctionCallImpl(
|
return FirFunctionCallImpl(
|
||||||
source,
|
|
||||||
typeRef,
|
typeRef,
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
contextReceiverArguments.toMutableOrEmpty(),
|
contextReceiverArguments.toMutableOrEmpty(),
|
||||||
@@ -60,6 +59,7 @@ open class FirFunctionCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotatio
|
|||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
dispatchReceiver,
|
dispatchReceiver,
|
||||||
extensionReceiver,
|
extensionReceiver,
|
||||||
|
source,
|
||||||
argumentList,
|
argumentList,
|
||||||
calleeReference,
|
calleeReference,
|
||||||
origin,
|
origin,
|
||||||
|
|||||||
+2
-2
@@ -37,25 +37,25 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
open class FirImplicitInvokeCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
open class FirImplicitInvokeCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||||
override var source: KtSourceElement? = null
|
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
||||||
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
|
||||||
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
||||||
|
override var source: KtSourceElement? = null
|
||||||
override var argumentList: FirArgumentList = FirEmptyArgumentList
|
override var argumentList: FirArgumentList = FirEmptyArgumentList
|
||||||
override lateinit var calleeReference: FirNamedReference
|
override lateinit var calleeReference: FirNamedReference
|
||||||
|
|
||||||
override fun build(): FirImplicitInvokeCall {
|
override fun build(): FirImplicitInvokeCall {
|
||||||
return FirImplicitInvokeCallImpl(
|
return FirImplicitInvokeCallImpl(
|
||||||
source,
|
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
contextReceiverArguments.toMutableOrEmpty(),
|
contextReceiverArguments.toMutableOrEmpty(),
|
||||||
typeArguments.toMutableOrEmpty(),
|
typeArguments.toMutableOrEmpty(),
|
||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
dispatchReceiver,
|
dispatchReceiver,
|
||||||
extensionReceiver,
|
extensionReceiver,
|
||||||
|
source,
|
||||||
argumentList,
|
argumentList,
|
||||||
calleeReference,
|
calleeReference,
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-2
@@ -36,12 +36,12 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
open class FirIntegerLiteralOperatorCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
open class FirIntegerLiteralOperatorCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||||
override var source: KtSourceElement? = null
|
|
||||||
override lateinit var typeRef: FirTypeRef
|
override lateinit var typeRef: FirTypeRef
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
||||||
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
|
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
|
||||||
override var explicitReceiver: FirExpression? = null
|
override var explicitReceiver: FirExpression? = null
|
||||||
|
override var source: KtSourceElement? = null
|
||||||
override var argumentList: FirArgumentList = FirEmptyArgumentList
|
override var argumentList: FirArgumentList = FirEmptyArgumentList
|
||||||
override lateinit var calleeReference: FirNamedReference
|
override lateinit var calleeReference: FirNamedReference
|
||||||
override lateinit var origin: FirFunctionCallOrigin
|
override lateinit var origin: FirFunctionCallOrigin
|
||||||
@@ -50,12 +50,12 @@ open class FirIntegerLiteralOperatorCallBuilder : FirAbstractFunctionCallBuilder
|
|||||||
|
|
||||||
override fun build(): FirIntegerLiteralOperatorCall {
|
override fun build(): FirIntegerLiteralOperatorCall {
|
||||||
return FirIntegerLiteralOperatorCallImpl(
|
return FirIntegerLiteralOperatorCallImpl(
|
||||||
source,
|
|
||||||
typeRef,
|
typeRef,
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
contextReceiverArguments.toMutableOrEmpty(),
|
contextReceiverArguments.toMutableOrEmpty(),
|
||||||
typeArguments.toMutableOrEmpty(),
|
typeArguments.toMutableOrEmpty(),
|
||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
|
source,
|
||||||
argumentList,
|
argumentList,
|
||||||
calleeReference,
|
calleeReference,
|
||||||
origin,
|
origin,
|
||||||
|
|||||||
+4
-4
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||||
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.FirQualifiedAccessExpressionBuilder
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirPropertyAccessExpressionImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirPropertyAccessExpressionImpl
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
@@ -33,8 +33,7 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
class FirPropertyAccessExpressionBuilder : FirQualifiedAccessBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
class FirPropertyAccessExpressionBuilder : FirQualifiedAccessExpressionBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||||
override var source: KtSourceElement? = null
|
|
||||||
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
lateinit var calleeReference: FirReference
|
lateinit var calleeReference: FirReference
|
||||||
@@ -43,12 +42,12 @@ class FirPropertyAccessExpressionBuilder : FirQualifiedAccessBuilder, FirAnnotat
|
|||||||
override var explicitReceiver: FirExpression? = null
|
override var explicitReceiver: FirExpression? = null
|
||||||
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
||||||
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
||||||
|
override var source: KtSourceElement? = null
|
||||||
val nonFatalDiagnostics: MutableList<ConeDiagnostic> = mutableListOf()
|
val nonFatalDiagnostics: MutableList<ConeDiagnostic> = mutableListOf()
|
||||||
|
|
||||||
@OptIn(FirImplementationDetail::class)
|
@OptIn(FirImplementationDetail::class)
|
||||||
override fun build(): FirPropertyAccessExpression {
|
override fun build(): FirPropertyAccessExpression {
|
||||||
return FirPropertyAccessExpressionImpl(
|
return FirPropertyAccessExpressionImpl(
|
||||||
source,
|
|
||||||
typeRef,
|
typeRef,
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
calleeReference,
|
calleeReference,
|
||||||
@@ -57,6 +56,7 @@ class FirPropertyAccessExpressionBuilder : FirQualifiedAccessBuilder, FirAnnotat
|
|||||||
explicitReceiver,
|
explicitReceiver,
|
||||||
dispatchReceiver,
|
dispatchReceiver,
|
||||||
extensionReceiver,
|
extensionReceiver,
|
||||||
|
source,
|
||||||
nonFatalDiagnostics.toMutableOrEmpty(),
|
nonFatalDiagnostics.toMutableOrEmpty(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-3
@@ -11,8 +11,9 @@ import org.jetbrains.kotlin.KtSourceElement
|
|||||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.visitors.*
|
import org.jetbrains.kotlin.fir.visitors.*
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -21,7 +22,8 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
interface FirQualifiedAccessBuilder {
|
interface FirQualifiedAccessExpressionBuilder {
|
||||||
|
abstract var typeRef: FirTypeRef
|
||||||
abstract val annotations: MutableList<FirAnnotation>
|
abstract val annotations: MutableList<FirAnnotation>
|
||||||
abstract val contextReceiverArguments: MutableList<FirExpression>
|
abstract val contextReceiverArguments: MutableList<FirExpression>
|
||||||
abstract val typeArguments: MutableList<FirTypeProjection>
|
abstract val typeArguments: MutableList<FirTypeProjection>
|
||||||
@@ -29,5 +31,5 @@ interface FirQualifiedAccessBuilder {
|
|||||||
abstract var dispatchReceiver: FirExpression
|
abstract var dispatchReceiver: FirExpression
|
||||||
abstract var extensionReceiver: FirExpression
|
abstract var extensionReceiver: FirExpression
|
||||||
abstract var source: KtSourceElement?
|
abstract var source: KtSourceElement?
|
||||||
fun build(): FirQualifiedAccess
|
fun build(): FirQualifiedAccessExpression
|
||||||
}
|
}
|
||||||
+4
-4
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
||||||
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.FirQualifiedAccessExpressionBuilder
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirThisReceiverExpressionImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirThisReceiverExpressionImpl
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
@@ -33,22 +33,22 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
class FirThisReceiverExpressionBuilder : FirQualifiedAccessBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
class FirThisReceiverExpressionBuilder : FirQualifiedAccessExpressionBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||||
override var source: KtSourceElement? = null
|
|
||||||
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
||||||
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
|
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
|
||||||
|
override var source: KtSourceElement? = null
|
||||||
lateinit var calleeReference: FirThisReference
|
lateinit var calleeReference: FirThisReference
|
||||||
var isImplicit: Boolean = false
|
var isImplicit: Boolean = false
|
||||||
|
|
||||||
override fun build(): FirThisReceiverExpression {
|
override fun build(): FirThisReceiverExpression {
|
||||||
return FirThisReceiverExpressionImpl(
|
return FirThisReceiverExpressionImpl(
|
||||||
source,
|
|
||||||
typeRef,
|
typeRef,
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
contextReceiverArguments.toMutableOrEmpty(),
|
contextReceiverArguments.toMutableOrEmpty(),
|
||||||
typeArguments.toMutableOrEmpty(),
|
typeArguments.toMutableOrEmpty(),
|
||||||
|
source,
|
||||||
calleeReference,
|
calleeReference,
|
||||||
isImplicit,
|
isImplicit,
|
||||||
)
|
)
|
||||||
|
|||||||
+5
-22
@@ -9,20 +9,13 @@ package org.jetbrains.kotlin.fir.expressions.builder
|
|||||||
|
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
|
||||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessBuilder
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirVariableAssignmentImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirVariableAssignmentImpl
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.*
|
import org.jetbrains.kotlin.fir.visitors.*
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -31,27 +24,17 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@FirBuilderDsl
|
@FirBuilderDsl
|
||||||
class FirVariableAssignmentBuilder : FirQualifiedAccessBuilder, FirAnnotationContainerBuilder {
|
class FirVariableAssignmentBuilder : FirAnnotationContainerBuilder {
|
||||||
lateinit var calleeReference: FirReference
|
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
|
||||||
override val contextReceiverArguments: MutableList<FirExpression> = mutableListOf()
|
|
||||||
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
|
|
||||||
override var explicitReceiver: FirExpression? = null
|
|
||||||
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
|
||||||
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
|
||||||
override var source: KtSourceElement? = null
|
override var source: KtSourceElement? = null
|
||||||
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
|
lateinit var lValue: FirExpression
|
||||||
lateinit var rValue: FirExpression
|
lateinit var rValue: FirExpression
|
||||||
|
|
||||||
override fun build(): FirVariableAssignment {
|
override fun build(): FirVariableAssignment {
|
||||||
return FirVariableAssignmentImpl(
|
return FirVariableAssignmentImpl(
|
||||||
calleeReference,
|
|
||||||
annotations.toMutableOrEmpty(),
|
|
||||||
contextReceiverArguments.toMutableOrEmpty(),
|
|
||||||
typeArguments.toMutableOrEmpty(),
|
|
||||||
explicitReceiver,
|
|
||||||
dispatchReceiver,
|
|
||||||
extensionReceiver,
|
|
||||||
source,
|
source,
|
||||||
|
annotations.toMutableOrEmpty(),
|
||||||
|
lValue,
|
||||||
rValue,
|
rValue,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user