[FIR] Fix resolving to star import member instead of builtin (^KT-48157 Fixed)
This commit is contained in:
Vendored
+1
-1
@@ -23,7 +23,7 @@ FILE: classifierAccessFromCompanion.kt
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val f: R|kotlin/Unit| = Q|Factory.Function|
|
||||
public final val f: R|kotlin/Unit| = R|kotlin/Unit|
|
||||
public get(): R|kotlin/Unit|
|
||||
|
||||
public final val x: R|Factory.Function.Default| = Q|Factory.Function.Default|
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ FILE: innerQualifier.kt
|
||||
}
|
||||
|
||||
}
|
||||
public final val x: R|kotlin/Unit| = Q|Outer.Inner|
|
||||
public final val x: R|kotlin/Unit| = R|kotlin/Unit|
|
||||
public get(): R|kotlin/Unit|
|
||||
public final val klass: R|kotlin/reflect/KClass<Outer.Inner>| = <getClass>(Q|Outer.Inner|)
|
||||
public get(): R|kotlin/reflect/KClass<Outer.Inner>|
|
||||
|
||||
+2
-2
@@ -59,8 +59,8 @@ FILE: qualifierPriority.kt
|
||||
}
|
||||
public final val def: R|D.E.F| = Q|D.E.F|
|
||||
public get(): R|D.E.F|
|
||||
public final val de: R|kotlin/Unit| = Q|D.E|
|
||||
public get(): R|kotlin/Unit|
|
||||
public final val de: R|kotlin/String| = Q|D|.R|/E|
|
||||
public get(): R|kotlin/String|
|
||||
public final enum class G : R|kotlin/Enum<G>| {
|
||||
private constructor(): R|G| {
|
||||
super<R|kotlin/Enum<G>|>()
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ val D.E get() = ""
|
||||
|
||||
val def = D.E.F // object
|
||||
// See KT-46409
|
||||
val de = D.<!NO_COMPANION_OBJECT!>E<!> // Should be: extension & no error, in fact: qualifier
|
||||
val de = D.E
|
||||
|
||||
enum class G {
|
||||
H;
|
||||
|
||||
+6
@@ -24117,6 +24117,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveToStarImportMemberInsteadOfBuiltin.kt")
|
||||
public void testResolveToStarImportMemberInsteadOfBuiltin() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveToStarImportMemberInsteadOfBuiltin.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
||||
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
||||
|
||||
+6
@@ -24117,6 +24117,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveToStarImportMemberInsteadOfBuiltin.kt")
|
||||
public void testResolveToStarImportMemberInsteadOfBuiltin() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveToStarImportMemberInsteadOfBuiltin.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
||||
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
||||
|
||||
+1
@@ -44,6 +44,7 @@ private fun ConeDiagnostic.toFirDiagnostic(
|
||||
is ConeFunctionExpectedError -> FirErrors.FUNCTION_EXPECTED.createOn(source, this.expression, this.type)
|
||||
is ConeResolutionToClassifierError -> FirErrors.RESOLUTION_TO_CLASSIFIER.createOn(source, this.classSymbol)
|
||||
is ConeHiddenCandidateError -> FirErrors.INVISIBLE_REFERENCE.createOn(source, this.candidateSymbol)
|
||||
is ConeNoCompanionObject -> FirErrors.NO_COMPANION_OBJECT.createOn(source, this.symbol)
|
||||
is ConeAmbiguityError -> when {
|
||||
applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol })
|
||||
applicability == CandidateApplicability.UNSAFE_CALL -> {
|
||||
|
||||
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import java.lang.annotation.ElementType
|
||||
|
||||
class FirCallResolver(
|
||||
private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents,
|
||||
@@ -73,7 +74,7 @@ class FirCallResolver(
|
||||
qualifiedResolver.reset()
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val functionCall = if (needTransformArguments) {
|
||||
functionCall.transformExplicitReceiver()
|
||||
components.context.withIncrementedQualifierPartIndex { functionCall.transformExplicitReceiver() }
|
||||
.also {
|
||||
components.dataFlowAnalyzer.enterQualifiedAccessExpression()
|
||||
functionCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
|
||||
@@ -82,51 +83,53 @@ class FirCallResolver(
|
||||
functionCall
|
||||
}
|
||||
|
||||
val name = functionCall.calleeReference.name
|
||||
val result = collectCandidates(functionCall, name)
|
||||
return components.context.withIncrementedQualifierPartIndex {
|
||||
val name = functionCall.calleeReference.name
|
||||
val result = collectCandidates(functionCall, name)
|
||||
|
||||
var forceCandidates: Collection<Candidate>? = null
|
||||
if (result.candidates.isEmpty()) {
|
||||
val newResult = collectCandidates(functionCall, name, CallKind.VariableAccess)
|
||||
if (newResult.candidates.isNotEmpty()) {
|
||||
forceCandidates = newResult.candidates
|
||||
var forceCandidates: Collection<Candidate>? = null
|
||||
if (result.candidates.isEmpty()) {
|
||||
val newResult = collectCandidates(functionCall, name, CallKind.VariableAccess)
|
||||
if (newResult.candidates.isNotEmpty()) {
|
||||
forceCandidates = newResult.candidates
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val nameReference = createResolvedNamedReference(
|
||||
functionCall.calleeReference,
|
||||
name,
|
||||
result.info,
|
||||
result.candidates,
|
||||
result.applicability,
|
||||
functionCall.explicitReceiver,
|
||||
expectedCallKind = if (forceCandidates != null) CallKind.VariableAccess else null,
|
||||
expectedCandidates = forceCandidates
|
||||
)
|
||||
|
||||
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
|
||||
val candidate = (nameReference as? FirNamedReferenceWithCandidate)?.candidate
|
||||
val resolvedReceiver = functionCall.explicitReceiver
|
||||
if (candidate != null && resolvedReceiver is FirResolvedQualifier) {
|
||||
resolvedReceiver.replaceResolvedToCompanionObject(candidate.isFromCompanionObjectTypeScope)
|
||||
}
|
||||
|
||||
// We need desugaring
|
||||
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
|
||||
functionCall.copy(
|
||||
explicitReceiver = candidate.callInfo.explicitReceiver,
|
||||
dispatchReceiver = candidate.dispatchReceiverExpression(),
|
||||
extensionReceiver = candidate.extensionReceiverExpression(),
|
||||
argumentList = candidate.callInfo.argumentList,
|
||||
val nameReference = createResolvedNamedReference(
|
||||
functionCall.calleeReference,
|
||||
name,
|
||||
result.info,
|
||||
result.candidates,
|
||||
result.applicability,
|
||||
functionCall.explicitReceiver,
|
||||
expectedCallKind = if (forceCandidates != null) CallKind.VariableAccess else null,
|
||||
expectedCandidates = forceCandidates
|
||||
)
|
||||
} else {
|
||||
resultExpression
|
||||
|
||||
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
|
||||
val candidate = (nameReference as? FirNamedReferenceWithCandidate)?.candidate
|
||||
val resolvedReceiver = functionCall.explicitReceiver
|
||||
if (candidate != null && resolvedReceiver is FirResolvedQualifier) {
|
||||
resolvedReceiver.replaceResolvedToCompanionObject(candidate.isFromCompanionObjectTypeScope)
|
||||
}
|
||||
|
||||
// We need desugaring
|
||||
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
|
||||
functionCall.copy(
|
||||
explicitReceiver = candidate.callInfo.explicitReceiver,
|
||||
dispatchReceiver = candidate.dispatchReceiverExpression(),
|
||||
extensionReceiver = candidate.extensionReceiverExpression(),
|
||||
argumentList = candidate.callInfo.argumentList,
|
||||
)
|
||||
} else {
|
||||
resultExpression
|
||||
}
|
||||
val typeRef = components.typeFromCallee(resultFunctionCall)
|
||||
if (typeRef.type is ConeKotlinErrorType) {
|
||||
resultFunctionCall.resultType = typeRef
|
||||
}
|
||||
return@withIncrementedQualifierPartIndex resultFunctionCall
|
||||
}
|
||||
val typeRef = components.typeFromCallee(resultFunctionCall)
|
||||
if (typeRef.type is ConeKotlinErrorType) {
|
||||
resultFunctionCall.resultType = typeRef
|
||||
}
|
||||
return resultFunctionCall
|
||||
}
|
||||
|
||||
private inline fun <reified Q : FirQualifiedAccess> Q.transformExplicitReceiver(): Q {
|
||||
@@ -216,97 +219,99 @@ class FirCallResolver(
|
||||
): FirStatement {
|
||||
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
|
||||
|
||||
qualifiedResolver.initProcessingQualifiedAccess(callee, qualifiedAccess.typeArguments)
|
||||
return components.context.withIncrementedQualifierPartIndex {
|
||||
qualifiedResolver.initProcessingQualifiedAccess(callee, qualifiedAccess.typeArguments)
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val qualifiedAccess = qualifiedAccess.transformExplicitReceiver<FirQualifiedAccess>()
|
||||
qualifiedResolver.replacedQualifier(qualifiedAccess)?.let { resolvedQualifierPart ->
|
||||
return resolvedQualifierPart
|
||||
}
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val qualifiedAccess = qualifiedAccess.transformExplicitReceiver<FirQualifiedAccess>()
|
||||
qualifiedResolver.replacedQualifier(qualifiedAccess)?.let { resolvedQualifierPart ->
|
||||
return@withIncrementedQualifierPartIndex resolvedQualifierPart
|
||||
}
|
||||
|
||||
var result = collectCandidates(qualifiedAccess, callee.name)
|
||||
var result = collectCandidates(qualifiedAccess, callee.name)
|
||||
|
||||
if (qualifiedAccess.explicitReceiver == null) {
|
||||
if (!result.applicability.isSuccess) {
|
||||
// We should run QualifierResolver if no successful candidates are available
|
||||
// Otherwise expression (even ambiguous) beat qualifier
|
||||
qualifiedResolver.tryResolveAsQualifier(qualifiedAccess.source)?.let { resolvedQualifier ->
|
||||
return resolvedQualifier
|
||||
if (qualifiedAccess.explicitReceiver == null) {
|
||||
if (!result.applicability.isSuccess) {
|
||||
// We should run QualifierResolver if no successful candidates are available
|
||||
// Otherwise expression (even ambiguous) beat qualifier
|
||||
qualifiedResolver.tryResolveAsQualifier(qualifiedAccess.source)?.let { resolvedQualifier ->
|
||||
return@withIncrementedQualifierPartIndex resolvedQualifier
|
||||
}
|
||||
}
|
||||
qualifiedResolver.reset()
|
||||
}
|
||||
|
||||
var functionCallExpected = false
|
||||
if (result.candidates.isEmpty() && qualifiedAccess !is FirFunctionCall) {
|
||||
val newResult = collectCandidates(qualifiedAccess, callee.name, CallKind.Function)
|
||||
if (newResult.candidates.isNotEmpty()) {
|
||||
result = newResult
|
||||
functionCallExpected = true
|
||||
}
|
||||
}
|
||||
qualifiedResolver.reset()
|
||||
}
|
||||
|
||||
var functionCallExpected = false
|
||||
if (result.candidates.isEmpty() && qualifiedAccess !is FirFunctionCall) {
|
||||
val newResult = collectCandidates(qualifiedAccess, callee.name, CallKind.Function)
|
||||
if (newResult.candidates.isNotEmpty()) {
|
||||
result = newResult
|
||||
functionCallExpected = true
|
||||
val reducedCandidates = result.candidates
|
||||
if (!acceptCandidates(reducedCandidates)) return@withIncrementedQualifierPartIndex qualifiedAccess
|
||||
|
||||
val nameReference = createResolvedNamedReference(
|
||||
callee,
|
||||
callee.name,
|
||||
result.info,
|
||||
reducedCandidates,
|
||||
result.applicability,
|
||||
qualifiedAccess.explicitReceiver,
|
||||
expectedCallKind = if (functionCallExpected) CallKind.Function else null
|
||||
)
|
||||
|
||||
val referencedSymbol = when (nameReference) {
|
||||
is FirResolvedNamedReference -> nameReference.resolvedSymbol
|
||||
is FirNamedReferenceWithCandidate -> nameReference.candidateSymbol
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
val reducedCandidates = result.candidates
|
||||
if (!acceptCandidates(reducedCandidates)) return qualifiedAccess
|
||||
val diagnostic = when (nameReference) {
|
||||
is FirErrorReferenceWithCandidate -> nameReference.diagnostic
|
||||
is FirErrorNamedReference -> nameReference.diagnostic
|
||||
else -> null
|
||||
}
|
||||
|
||||
val nameReference = createResolvedNamedReference(
|
||||
callee,
|
||||
callee.name,
|
||||
result.info,
|
||||
reducedCandidates,
|
||||
result.applicability,
|
||||
qualifiedAccess.explicitReceiver,
|
||||
expectedCallKind = if (functionCallExpected) CallKind.Function else null
|
||||
)
|
||||
(qualifiedAccess.explicitReceiver as? FirResolvedQualifier)?.replaceResolvedToCompanionObject(
|
||||
reducedCandidates.isNotEmpty() && reducedCandidates.all { it.isFromCompanionObjectTypeScope }
|
||||
)
|
||||
|
||||
val referencedSymbol = when (nameReference) {
|
||||
is FirResolvedNamedReference -> nameReference.resolvedSymbol
|
||||
is FirNamedReferenceWithCandidate -> nameReference.candidateSymbol
|
||||
else -> null
|
||||
}
|
||||
|
||||
val diagnostic = when (nameReference) {
|
||||
is FirErrorReferenceWithCandidate -> nameReference.diagnostic
|
||||
is FirErrorNamedReference -> nameReference.diagnostic
|
||||
else -> null
|
||||
}
|
||||
|
||||
(qualifiedAccess.explicitReceiver as? FirResolvedQualifier)?.replaceResolvedToCompanionObject(
|
||||
reducedCandidates.isNotEmpty() && reducedCandidates.all { it.isFromCompanionObjectTypeScope }
|
||||
)
|
||||
|
||||
when {
|
||||
referencedSymbol is FirClassLikeSymbol<*> -> {
|
||||
return components.buildResolvedQualifierForClass(
|
||||
referencedSymbol,
|
||||
nameReference.source,
|
||||
qualifiedAccess.typeArguments,
|
||||
diagnostic,
|
||||
nonFatalDiagnostics = extractNonFatalDiagnostics(
|
||||
nameReference.source,
|
||||
qualifiedAccess.explicitReceiver,
|
||||
when {
|
||||
referencedSymbol is FirClassLikeSymbol<*> -> {
|
||||
return@withIncrementedQualifierPartIndex components.buildResolvedQualifierForClass(
|
||||
referencedSymbol,
|
||||
(qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics
|
||||
nameReference.source,
|
||||
qualifiedAccess.typeArguments,
|
||||
diagnostic,
|
||||
nonFatalDiagnostics = extractNonFatalDiagnostics(
|
||||
nameReference.source,
|
||||
qualifiedAccess.explicitReceiver,
|
||||
referencedSymbol,
|
||||
(qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
referencedSymbol is FirTypeParameterSymbol && referencedSymbol.fir.isReified -> {
|
||||
return buildResolvedReifiedParameterReference {
|
||||
source = nameReference.source
|
||||
symbol = referencedSymbol
|
||||
typeRef = typeForReifiedParameterReference(this)
|
||||
}
|
||||
referencedSymbol is FirTypeParameterSymbol && referencedSymbol.fir.isReified -> {
|
||||
return@withIncrementedQualifierPartIndex buildResolvedReifiedParameterReference {
|
||||
source = nameReference.source
|
||||
symbol = referencedSymbol
|
||||
typeRef = typeForReifiedParameterReference(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var resultExpression = qualifiedAccess.transformCalleeReference(StoreNameReference, nameReference)
|
||||
if (reducedCandidates.size == 1) {
|
||||
val candidate = reducedCandidates.single()
|
||||
resultExpression = resultExpression.transformDispatchReceiver(StoreReceiver, candidate.dispatchReceiverExpression())
|
||||
resultExpression = resultExpression.transformExtensionReceiver(StoreReceiver, candidate.extensionReceiverExpression())
|
||||
var resultExpression = qualifiedAccess.transformCalleeReference(StoreNameReference, nameReference)
|
||||
if (reducedCandidates.size == 1) {
|
||||
val candidate = reducedCandidates.single()
|
||||
resultExpression = resultExpression.transformDispatchReceiver(StoreReceiver, candidate.dispatchReceiverExpression())
|
||||
resultExpression = resultExpression.transformExtensionReceiver(StoreReceiver, candidate.extensionReceiverExpression())
|
||||
}
|
||||
if (resultExpression is FirExpression) transformer.storeTypeFromCallee(resultExpression)
|
||||
return@withIncrementedQualifierPartIndex resultExpression
|
||||
}
|
||||
if (resultExpression is FirExpression) transformer.storeTypeFromCallee(resultExpression)
|
||||
return resultExpression
|
||||
}
|
||||
|
||||
private fun extractNonFatalDiagnostics(
|
||||
@@ -700,6 +705,7 @@ class FirCallResolver(
|
||||
val candidate = candidates.single()
|
||||
val diagnostic = when (applicability) {
|
||||
CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate.symbol)
|
||||
CandidateApplicability.NO_COMPANION_OBJECT -> ConeNoCompanionObject(candidate.symbol as FirRegularClassSymbol)
|
||||
else -> ConeInapplicableCandidateError(applicability, candidate)
|
||||
}
|
||||
createErrorReferenceWithExistingCandidate(
|
||||
|
||||
+10
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
@@ -48,7 +49,8 @@ class CandidateFactory private constructor(
|
||||
scope: FirScope?,
|
||||
dispatchReceiverValue: ReceiverValue? = null,
|
||||
extensionReceiverValue: ReceiverValue? = null,
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
|
||||
objectsByName: Boolean = false
|
||||
): Candidate {
|
||||
val result = Candidate(
|
||||
symbol, dispatchReceiverValue, extensionReceiverValue,
|
||||
@@ -72,6 +74,13 @@ class CandidateFactory private constructor(
|
||||
if (symbol is FirValueParameterSymbol || symbol is FirPropertySymbol && symbol.isLocal || symbol is FirBackingFieldSymbol) {
|
||||
result.addDiagnostic(Unsupported("References to variables aren't supported yet", callSite.calleeReference.source))
|
||||
}
|
||||
} else if (objectsByName &&
|
||||
context.bodyResolveContext.qualifierPartIndexFromEnd == 0 &&
|
||||
symbol is FirRegularClassSymbol &&
|
||||
symbol.classKind != ClassKind.OBJECT &&
|
||||
symbol.companionObjectSymbol == null
|
||||
) {
|
||||
result.addDiagnostic(NoCompanionObject)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
+2
@@ -70,6 +70,8 @@ class InapplicableWrongReceiver(
|
||||
val actualType: ConeKotlinType? = null,
|
||||
) : ResolutionDiagnostic(INAPPLICABLE_WRONG_RECEIVER)
|
||||
|
||||
object NoCompanionObject : ResolutionDiagnostic(NO_COMPANION_OBJECT)
|
||||
|
||||
class UnsafeCall(val actualType: ConeKotlinType) : ResolutionDiagnostic(UNSAFE_CALL)
|
||||
|
||||
object LowerPriorityToPreserveCompatibilityDiagnostic : ResolutionDiagnostic(RESOLVED_NEED_PRESERVE_COMPATIBILITY)
|
||||
|
||||
+4
-2
@@ -76,7 +76,8 @@ private class TowerScopeLevelProcessor(
|
||||
dispatchReceiverValue: ReceiverValue?,
|
||||
extensionReceiverValue: ReceiverValue?,
|
||||
scope: FirScope,
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue?
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue?,
|
||||
objectsByName: Boolean
|
||||
) {
|
||||
resultCollector.consumeCandidate(
|
||||
group, candidateFactory.createCandidate(
|
||||
@@ -86,7 +87,8 @@ private class TowerScopeLevelProcessor(
|
||||
scope,
|
||||
dispatchReceiverValue,
|
||||
extensionReceiverValue,
|
||||
builtInExtensionFunctionReceiverValue
|
||||
builtInExtensionFunctionReceiverValue,
|
||||
objectsByName
|
||||
), candidateFactory.context
|
||||
)
|
||||
}
|
||||
|
||||
+4
-2
@@ -52,7 +52,8 @@ abstract class TowerScopeLevel {
|
||||
dispatchReceiverValue: ReceiverValue?,
|
||||
extensionReceiverValue: ReceiverValue?,
|
||||
scope: FirScope,
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
|
||||
objectsByName: Boolean = false
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -335,7 +336,8 @@ class ScopeTowerLevel(
|
||||
processor.consumeCandidate(
|
||||
it, dispatchReceiverValue = null,
|
||||
extensionReceiverValue = null,
|
||||
scope = scope
|
||||
scope = scope,
|
||||
objectsByName = true
|
||||
)
|
||||
}
|
||||
return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND
|
||||
|
||||
+6
@@ -70,6 +70,12 @@ class ConeInapplicableCandidateError(
|
||||
override val reason: String get() = "Inapplicable($applicability): ${describeSymbol(candidate.symbol)}"
|
||||
}
|
||||
|
||||
class ConeNoCompanionObject(
|
||||
val symbol: FirRegularClassSymbol
|
||||
) : ConeDiagnostic() {
|
||||
override val reason: String get() = "Classifier ''$symbol'' does not have a companion object, and thus must be initialized here"
|
||||
}
|
||||
|
||||
class ConeConstraintSystemHasContradiction(
|
||||
val candidate: Candidate,
|
||||
) : ConeDiagnostic() {
|
||||
|
||||
+14
-3
@@ -75,7 +75,7 @@ class BodyResolveContext(
|
||||
get() = towerDataContextsForClassParts.towerDataContextForCallableReferences
|
||||
|
||||
@set:PrivateForInline
|
||||
var containers: MutableList<FirDeclaration> = mutableListOf()
|
||||
var containers: ArrayDeque<FirDeclaration> = ArrayDeque()
|
||||
|
||||
@set:PrivateForInline
|
||||
var containingClass: FirRegularClass? = null
|
||||
@@ -118,7 +118,7 @@ class BodyResolveContext(
|
||||
return try {
|
||||
f()
|
||||
} finally {
|
||||
containers.removeAt(containers.size - 1)
|
||||
containers.removeLast()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ class BodyResolveContext(
|
||||
return try {
|
||||
f()
|
||||
} finally {
|
||||
containers.removeAt(containers.size - 1)
|
||||
containers.removeLast()
|
||||
containingClass = oldContainingClass
|
||||
}
|
||||
}
|
||||
@@ -172,6 +172,17 @@ class BodyResolveContext(
|
||||
}
|
||||
}
|
||||
|
||||
var qualifierPartIndexFromEnd: Int = -1
|
||||
|
||||
inline fun <R> withIncrementedQualifierPartIndex(l: () -> R): R {
|
||||
qualifierPartIndexFromEnd++
|
||||
return try {
|
||||
l()
|
||||
} finally {
|
||||
qualifierPartIndexFromEnd--
|
||||
}
|
||||
}
|
||||
|
||||
@PrivateForInline
|
||||
fun replaceTowerDataContext(newContext: FirTowerDataContext) {
|
||||
towerDataContextsForClassParts.currentContext = newContext
|
||||
|
||||
+9
-4
@@ -837,9 +837,11 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
|
||||
callableReferenceAccess.transformAnnotations(transformer, data)
|
||||
val explicitReceiver = callableReferenceAccess.explicitReceiver
|
||||
val transformedLHS = explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent)?.apply {
|
||||
if (this is FirResolvedQualifier && callableReferenceAccess.hasQuestionMarkAtLHS) {
|
||||
replaceIsNullableLHSForCallableReference(true)
|
||||
val transformedLHS = context.withIncrementedQualifierPartIndex {
|
||||
explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent)?.apply {
|
||||
if (this is FirResolvedQualifier && callableReferenceAccess.hasQuestionMarkAtLHS) {
|
||||
replaceIsNullableLHSForCallableReference(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -867,7 +869,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
} else {
|
||||
data
|
||||
}
|
||||
val transformedGetClassCall = transformExpression(getClassCall, dataWithExpectedType) as FirGetClassCall
|
||||
|
||||
val transformedGetClassCall = context.withIncrementedQualifierPartIndex {
|
||||
transformExpression(getClassCall, dataWithExpectedType) as FirGetClassCall
|
||||
}
|
||||
|
||||
val typeOfExpression = when (val lhs = transformedGetClassCall.argument) {
|
||||
is FirResolvedQualifier -> {
|
||||
|
||||
+1
@@ -13,6 +13,7 @@ enum class CandidateApplicability {
|
||||
INAPPLICABLE_ARGUMENTS_MAPPING_ERROR, // arguments not mapped to parameters (i.e. different size of arguments and parameters)
|
||||
INAPPLICABLE, // arguments have wrong types
|
||||
INAPPLICABLE_MODIFIER, // no expected modifier (eg infix call on non-infix function)
|
||||
NO_COMPANION_OBJECT, // Classifier does not have a companion object
|
||||
IMPOSSIBLE_TO_GENERATE, // access to outer class from nested
|
||||
RUNTIME_ERROR, // problems with visibility
|
||||
UNSAFE_CALL, // receiver or argument nullability doesn't match
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
package test
|
||||
|
||||
import test.C.E1
|
||||
@@ -17,7 +16,6 @@ class A {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
// Note: FIR resolve this to test/C instead of test/A.B.C
|
||||
C
|
||||
D()
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// FIR_IDENTICAL
|
||||
// https://youtrack.jetbrains.com/issue/KT-48157
|
||||
|
||||
import TestEnum.*
|
||||
|
||||
enum class TestEnum {
|
||||
Annotation,
|
||||
Collection,
|
||||
Set,
|
||||
List,
|
||||
Map,
|
||||
Function,
|
||||
Enum
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val x1 = Annotation
|
||||
val x2 = Collection
|
||||
val x3 = Set
|
||||
val x4 = List
|
||||
val x5 = Map
|
||||
val x6 = Function
|
||||
val x7 = Enum
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public final enum class TestEnum : kotlin.Enum<TestEnum> {
|
||||
enum entry Annotation
|
||||
|
||||
enum entry Collection
|
||||
|
||||
enum entry Set
|
||||
|
||||
enum entry List
|
||||
|
||||
enum entry Map
|
||||
|
||||
enum entry Function
|
||||
|
||||
enum entry Enum
|
||||
|
||||
private constructor TestEnum()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: TestEnum): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<TestEnum!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): TestEnum
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<TestEnum>
|
||||
}
|
||||
Generated
+6
@@ -24129,6 +24129,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveToStarImportMemberInsteadOfBuiltin.kt")
|
||||
public void testResolveToStarImportMemberInsteadOfBuiltin() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveToStarImportMemberInsteadOfBuiltin.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
||||
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
||||
|
||||
+6
@@ -24117,6 +24117,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveToStarImportMemberInsteadOfBuiltin.kt")
|
||||
public void testResolveToStarImportMemberInsteadOfBuiltin() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveToStarImportMemberInsteadOfBuiltin.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
||||
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
||||
|
||||
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in <local>: test) class Conflict
|
||||
0: (in test.Conflict) companion object
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in <local>: test) class Conflict
|
||||
0: (in test) object Conflict
|
||||
Reference in New Issue
Block a user