[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|>()
|
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 get(): R|kotlin/Unit|
|
||||||
|
|
||||||
public final val x: R|Factory.Function.Default| = Q|Factory.Function.Default|
|
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 get(): R|kotlin/Unit|
|
||||||
public final val klass: R|kotlin/reflect/KClass<Outer.Inner>| = <getClass>(Q|Outer.Inner|)
|
public final val klass: R|kotlin/reflect/KClass<Outer.Inner>| = <getClass>(Q|Outer.Inner|)
|
||||||
public get(): R|kotlin/reflect/KClass<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 final val def: R|D.E.F| = Q|D.E.F|
|
||||||
public get(): R|D.E.F|
|
public get(): R|D.E.F|
|
||||||
public final val de: R|kotlin/Unit| = Q|D.E|
|
public final val de: R|kotlin/String| = Q|D|.R|/E|
|
||||||
public get(): R|kotlin/Unit|
|
public get(): R|kotlin/String|
|
||||||
public final enum class G : R|kotlin/Enum<G>| {
|
public final enum class G : R|kotlin/Enum<G>| {
|
||||||
private constructor(): R|G| {
|
private constructor(): R|G| {
|
||||||
super<R|kotlin/Enum<G>|>()
|
super<R|kotlin/Enum<G>|>()
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ val D.E get() = ""
|
|||||||
|
|
||||||
val def = D.E.F // object
|
val def = D.E.F // object
|
||||||
// See KT-46409
|
// 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 {
|
enum class G {
|
||||||
H;
|
H;
|
||||||
|
|||||||
+6
@@ -24117,6 +24117,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
|
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
|
@Test
|
||||||
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
||||||
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
||||||
|
|||||||
+6
@@ -24117,6 +24117,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
|
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
|
@Test
|
||||||
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
||||||
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
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 ConeFunctionExpectedError -> FirErrors.FUNCTION_EXPECTED.createOn(source, this.expression, this.type)
|
||||||
is ConeResolutionToClassifierError -> FirErrors.RESOLUTION_TO_CLASSIFIER.createOn(source, this.classSymbol)
|
is ConeResolutionToClassifierError -> FirErrors.RESOLUTION_TO_CLASSIFIER.createOn(source, this.classSymbol)
|
||||||
is ConeHiddenCandidateError -> FirErrors.INVISIBLE_REFERENCE.createOn(source, this.candidateSymbol)
|
is ConeHiddenCandidateError -> FirErrors.INVISIBLE_REFERENCE.createOn(source, this.candidateSymbol)
|
||||||
|
is ConeNoCompanionObject -> FirErrors.NO_COMPANION_OBJECT.createOn(source, this.symbol)
|
||||||
is ConeAmbiguityError -> when {
|
is ConeAmbiguityError -> when {
|
||||||
applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol })
|
applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol })
|
||||||
applicability == CandidateApplicability.UNSAFE_CALL -> {
|
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.CandidateApplicability
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import java.lang.annotation.ElementType
|
||||||
|
|
||||||
class FirCallResolver(
|
class FirCallResolver(
|
||||||
private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents,
|
private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents,
|
||||||
@@ -73,7 +74,7 @@ class FirCallResolver(
|
|||||||
qualifiedResolver.reset()
|
qualifiedResolver.reset()
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
val functionCall = if (needTransformArguments) {
|
val functionCall = if (needTransformArguments) {
|
||||||
functionCall.transformExplicitReceiver()
|
components.context.withIncrementedQualifierPartIndex { functionCall.transformExplicitReceiver() }
|
||||||
.also {
|
.also {
|
||||||
components.dataFlowAnalyzer.enterQualifiedAccessExpression()
|
components.dataFlowAnalyzer.enterQualifiedAccessExpression()
|
||||||
functionCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
|
functionCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
|
||||||
@@ -82,51 +83,53 @@ class FirCallResolver(
|
|||||||
functionCall
|
functionCall
|
||||||
}
|
}
|
||||||
|
|
||||||
val name = functionCall.calleeReference.name
|
return components.context.withIncrementedQualifierPartIndex {
|
||||||
val result = collectCandidates(functionCall, name)
|
val name = functionCall.calleeReference.name
|
||||||
|
val result = collectCandidates(functionCall, name)
|
||||||
|
|
||||||
var forceCandidates: Collection<Candidate>? = null
|
var forceCandidates: Collection<Candidate>? = null
|
||||||
if (result.candidates.isEmpty()) {
|
if (result.candidates.isEmpty()) {
|
||||||
val newResult = collectCandidates(functionCall, name, CallKind.VariableAccess)
|
val newResult = collectCandidates(functionCall, name, CallKind.VariableAccess)
|
||||||
if (newResult.candidates.isNotEmpty()) {
|
if (newResult.candidates.isNotEmpty()) {
|
||||||
forceCandidates = newResult.candidates
|
forceCandidates = newResult.candidates
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val nameReference = createResolvedNamedReference(
|
val nameReference = createResolvedNamedReference(
|
||||||
functionCall.calleeReference,
|
functionCall.calleeReference,
|
||||||
name,
|
name,
|
||||||
result.info,
|
result.info,
|
||||||
result.candidates,
|
result.candidates,
|
||||||
result.applicability,
|
result.applicability,
|
||||||
functionCall.explicitReceiver,
|
functionCall.explicitReceiver,
|
||||||
expectedCallKind = if (forceCandidates != null) CallKind.VariableAccess else null,
|
expectedCallKind = if (forceCandidates != null) CallKind.VariableAccess else null,
|
||||||
expectedCandidates = forceCandidates
|
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,
|
|
||||||
)
|
)
|
||||||
} 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 {
|
private inline fun <reified Q : FirQualifiedAccess> Q.transformExplicitReceiver(): Q {
|
||||||
@@ -216,97 +219,99 @@ class FirCallResolver(
|
|||||||
): FirStatement {
|
): FirStatement {
|
||||||
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
|
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")
|
@Suppress("NAME_SHADOWING")
|
||||||
val qualifiedAccess = qualifiedAccess.transformExplicitReceiver<FirQualifiedAccess>()
|
val qualifiedAccess = qualifiedAccess.transformExplicitReceiver<FirQualifiedAccess>()
|
||||||
qualifiedResolver.replacedQualifier(qualifiedAccess)?.let { resolvedQualifierPart ->
|
qualifiedResolver.replacedQualifier(qualifiedAccess)?.let { resolvedQualifierPart ->
|
||||||
return resolvedQualifierPart
|
return@withIncrementedQualifierPartIndex resolvedQualifierPart
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = collectCandidates(qualifiedAccess, callee.name)
|
var result = collectCandidates(qualifiedAccess, callee.name)
|
||||||
|
|
||||||
if (qualifiedAccess.explicitReceiver == null) {
|
if (qualifiedAccess.explicitReceiver == null) {
|
||||||
if (!result.applicability.isSuccess) {
|
if (!result.applicability.isSuccess) {
|
||||||
// We should run QualifierResolver if no successful candidates are available
|
// We should run QualifierResolver if no successful candidates are available
|
||||||
// Otherwise expression (even ambiguous) beat qualifier
|
// Otherwise expression (even ambiguous) beat qualifier
|
||||||
qualifiedResolver.tryResolveAsQualifier(qualifiedAccess.source)?.let { resolvedQualifier ->
|
qualifiedResolver.tryResolveAsQualifier(qualifiedAccess.source)?.let { resolvedQualifier ->
|
||||||
return 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
|
val reducedCandidates = result.candidates
|
||||||
if (result.candidates.isEmpty() && qualifiedAccess !is FirFunctionCall) {
|
if (!acceptCandidates(reducedCandidates)) return@withIncrementedQualifierPartIndex qualifiedAccess
|
||||||
val newResult = collectCandidates(qualifiedAccess, callee.name, CallKind.Function)
|
|
||||||
if (newResult.candidates.isNotEmpty()) {
|
val nameReference = createResolvedNamedReference(
|
||||||
result = newResult
|
callee,
|
||||||
functionCallExpected = true
|
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
|
val diagnostic = when (nameReference) {
|
||||||
if (!acceptCandidates(reducedCandidates)) return qualifiedAccess
|
is FirErrorReferenceWithCandidate -> nameReference.diagnostic
|
||||||
|
is FirErrorNamedReference -> nameReference.diagnostic
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
val nameReference = createResolvedNamedReference(
|
(qualifiedAccess.explicitReceiver as? FirResolvedQualifier)?.replaceResolvedToCompanionObject(
|
||||||
callee,
|
reducedCandidates.isNotEmpty() && reducedCandidates.all { it.isFromCompanionObjectTypeScope }
|
||||||
callee.name,
|
)
|
||||||
result.info,
|
|
||||||
reducedCandidates,
|
|
||||||
result.applicability,
|
|
||||||
qualifiedAccess.explicitReceiver,
|
|
||||||
expectedCallKind = if (functionCallExpected) CallKind.Function else null
|
|
||||||
)
|
|
||||||
|
|
||||||
val referencedSymbol = when (nameReference) {
|
when {
|
||||||
is FirResolvedNamedReference -> nameReference.resolvedSymbol
|
referencedSymbol is FirClassLikeSymbol<*> -> {
|
||||||
is FirNamedReferenceWithCandidate -> nameReference.candidateSymbol
|
return@withIncrementedQualifierPartIndex components.buildResolvedQualifierForClass(
|
||||||
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,
|
|
||||||
referencedSymbol,
|
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 -> {
|
||||||
referencedSymbol is FirTypeParameterSymbol && referencedSymbol.fir.isReified -> {
|
return@withIncrementedQualifierPartIndex buildResolvedReifiedParameterReference {
|
||||||
return buildResolvedReifiedParameterReference {
|
source = nameReference.source
|
||||||
source = nameReference.source
|
symbol = referencedSymbol
|
||||||
symbol = referencedSymbol
|
typeRef = typeForReifiedParameterReference(this)
|
||||||
typeRef = typeForReifiedParameterReference(this)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var resultExpression = qualifiedAccess.transformCalleeReference(StoreNameReference, nameReference)
|
var resultExpression = qualifiedAccess.transformCalleeReference(StoreNameReference, nameReference)
|
||||||
if (reducedCandidates.size == 1) {
|
if (reducedCandidates.size == 1) {
|
||||||
val candidate = reducedCandidates.single()
|
val candidate = reducedCandidates.single()
|
||||||
resultExpression = resultExpression.transformDispatchReceiver(StoreReceiver, candidate.dispatchReceiverExpression())
|
resultExpression = resultExpression.transformDispatchReceiver(StoreReceiver, candidate.dispatchReceiverExpression())
|
||||||
resultExpression = resultExpression.transformExtensionReceiver(StoreReceiver, candidate.extensionReceiverExpression())
|
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(
|
private fun extractNonFatalDiagnostics(
|
||||||
@@ -700,6 +705,7 @@ class FirCallResolver(
|
|||||||
val candidate = candidates.single()
|
val candidate = candidates.single()
|
||||||
val diagnostic = when (applicability) {
|
val diagnostic = when (applicability) {
|
||||||
CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate.symbol)
|
CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate.symbol)
|
||||||
|
CandidateApplicability.NO_COMPANION_OBJECT -> ConeNoCompanionObject(candidate.symbol as FirRegularClassSymbol)
|
||||||
else -> ConeInapplicableCandidateError(applicability, candidate)
|
else -> ConeInapplicableCandidateError(applicability, candidate)
|
||||||
}
|
}
|
||||||
createErrorReferenceWithExistingCandidate(
|
createErrorReferenceWithExistingCandidate(
|
||||||
|
|||||||
+10
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
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.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
@@ -48,7 +49,8 @@ class CandidateFactory private constructor(
|
|||||||
scope: FirScope?,
|
scope: FirScope?,
|
||||||
dispatchReceiverValue: ReceiverValue? = null,
|
dispatchReceiverValue: ReceiverValue? = null,
|
||||||
extensionReceiverValue: ReceiverValue? = null,
|
extensionReceiverValue: ReceiverValue? = null,
|
||||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
|
||||||
|
objectsByName: Boolean = false
|
||||||
): Candidate {
|
): Candidate {
|
||||||
val result = Candidate(
|
val result = Candidate(
|
||||||
symbol, dispatchReceiverValue, extensionReceiverValue,
|
symbol, dispatchReceiverValue, extensionReceiverValue,
|
||||||
@@ -72,6 +74,13 @@ class CandidateFactory private constructor(
|
|||||||
if (symbol is FirValueParameterSymbol || symbol is FirPropertySymbol && symbol.isLocal || symbol is FirBackingFieldSymbol) {
|
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))
|
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
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -70,6 +70,8 @@ class InapplicableWrongReceiver(
|
|||||||
val actualType: ConeKotlinType? = null,
|
val actualType: ConeKotlinType? = null,
|
||||||
) : ResolutionDiagnostic(INAPPLICABLE_WRONG_RECEIVER)
|
) : ResolutionDiagnostic(INAPPLICABLE_WRONG_RECEIVER)
|
||||||
|
|
||||||
|
object NoCompanionObject : ResolutionDiagnostic(NO_COMPANION_OBJECT)
|
||||||
|
|
||||||
class UnsafeCall(val actualType: ConeKotlinType) : ResolutionDiagnostic(UNSAFE_CALL)
|
class UnsafeCall(val actualType: ConeKotlinType) : ResolutionDiagnostic(UNSAFE_CALL)
|
||||||
|
|
||||||
object LowerPriorityToPreserveCompatibilityDiagnostic : ResolutionDiagnostic(RESOLVED_NEED_PRESERVE_COMPATIBILITY)
|
object LowerPriorityToPreserveCompatibilityDiagnostic : ResolutionDiagnostic(RESOLVED_NEED_PRESERVE_COMPATIBILITY)
|
||||||
|
|||||||
+4
-2
@@ -76,7 +76,8 @@ private class TowerScopeLevelProcessor(
|
|||||||
dispatchReceiverValue: ReceiverValue?,
|
dispatchReceiverValue: ReceiverValue?,
|
||||||
extensionReceiverValue: ReceiverValue?,
|
extensionReceiverValue: ReceiverValue?,
|
||||||
scope: FirScope,
|
scope: FirScope,
|
||||||
builtInExtensionFunctionReceiverValue: ReceiverValue?
|
builtInExtensionFunctionReceiverValue: ReceiverValue?,
|
||||||
|
objectsByName: Boolean
|
||||||
) {
|
) {
|
||||||
resultCollector.consumeCandidate(
|
resultCollector.consumeCandidate(
|
||||||
group, candidateFactory.createCandidate(
|
group, candidateFactory.createCandidate(
|
||||||
@@ -86,7 +87,8 @@ private class TowerScopeLevelProcessor(
|
|||||||
scope,
|
scope,
|
||||||
dispatchReceiverValue,
|
dispatchReceiverValue,
|
||||||
extensionReceiverValue,
|
extensionReceiverValue,
|
||||||
builtInExtensionFunctionReceiverValue
|
builtInExtensionFunctionReceiverValue,
|
||||||
|
objectsByName
|
||||||
), candidateFactory.context
|
), candidateFactory.context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -52,7 +52,8 @@ abstract class TowerScopeLevel {
|
|||||||
dispatchReceiverValue: ReceiverValue?,
|
dispatchReceiverValue: ReceiverValue?,
|
||||||
extensionReceiverValue: ReceiverValue?,
|
extensionReceiverValue: ReceiverValue?,
|
||||||
scope: FirScope,
|
scope: FirScope,
|
||||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
|
||||||
|
objectsByName: Boolean = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,7 +336,8 @@ class ScopeTowerLevel(
|
|||||||
processor.consumeCandidate(
|
processor.consumeCandidate(
|
||||||
it, dispatchReceiverValue = null,
|
it, dispatchReceiverValue = null,
|
||||||
extensionReceiverValue = null,
|
extensionReceiverValue = null,
|
||||||
scope = scope
|
scope = scope,
|
||||||
|
objectsByName = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND
|
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)}"
|
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(
|
class ConeConstraintSystemHasContradiction(
|
||||||
val candidate: Candidate,
|
val candidate: Candidate,
|
||||||
) : ConeDiagnostic() {
|
) : ConeDiagnostic() {
|
||||||
|
|||||||
+14
-3
@@ -75,7 +75,7 @@ class BodyResolveContext(
|
|||||||
get() = towerDataContextsForClassParts.towerDataContextForCallableReferences
|
get() = towerDataContextsForClassParts.towerDataContextForCallableReferences
|
||||||
|
|
||||||
@set:PrivateForInline
|
@set:PrivateForInline
|
||||||
var containers: MutableList<FirDeclaration> = mutableListOf()
|
var containers: ArrayDeque<FirDeclaration> = ArrayDeque()
|
||||||
|
|
||||||
@set:PrivateForInline
|
@set:PrivateForInline
|
||||||
var containingClass: FirRegularClass? = null
|
var containingClass: FirRegularClass? = null
|
||||||
@@ -118,7 +118,7 @@ class BodyResolveContext(
|
|||||||
return try {
|
return try {
|
||||||
f()
|
f()
|
||||||
} finally {
|
} finally {
|
||||||
containers.removeAt(containers.size - 1)
|
containers.removeLast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ class BodyResolveContext(
|
|||||||
return try {
|
return try {
|
||||||
f()
|
f()
|
||||||
} finally {
|
} finally {
|
||||||
containers.removeAt(containers.size - 1)
|
containers.removeLast()
|
||||||
containingClass = oldContainingClass
|
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
|
@PrivateForInline
|
||||||
fun replaceTowerDataContext(newContext: FirTowerDataContext) {
|
fun replaceTowerDataContext(newContext: FirTowerDataContext) {
|
||||||
towerDataContextsForClassParts.currentContext = newContext
|
towerDataContextsForClassParts.currentContext = newContext
|
||||||
|
|||||||
+9
-4
@@ -837,9 +837,11 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
|
|
||||||
callableReferenceAccess.transformAnnotations(transformer, data)
|
callableReferenceAccess.transformAnnotations(transformer, data)
|
||||||
val explicitReceiver = callableReferenceAccess.explicitReceiver
|
val explicitReceiver = callableReferenceAccess.explicitReceiver
|
||||||
val transformedLHS = explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent)?.apply {
|
val transformedLHS = context.withIncrementedQualifierPartIndex {
|
||||||
if (this is FirResolvedQualifier && callableReferenceAccess.hasQuestionMarkAtLHS) {
|
explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent)?.apply {
|
||||||
replaceIsNullableLHSForCallableReference(true)
|
if (this is FirResolvedQualifier && callableReferenceAccess.hasQuestionMarkAtLHS) {
|
||||||
|
replaceIsNullableLHSForCallableReference(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -867,7 +869,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
} else {
|
} else {
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
val transformedGetClassCall = transformExpression(getClassCall, dataWithExpectedType) as FirGetClassCall
|
|
||||||
|
val transformedGetClassCall = context.withIncrementedQualifierPartIndex {
|
||||||
|
transformExpression(getClassCall, dataWithExpectedType) as FirGetClassCall
|
||||||
|
}
|
||||||
|
|
||||||
val typeOfExpression = when (val lhs = transformedGetClassCall.argument) {
|
val typeOfExpression = when (val lhs = transformedGetClassCall.argument) {
|
||||||
is FirResolvedQualifier -> {
|
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_MAPPING_ERROR, // arguments not mapped to parameters (i.e. different size of arguments and parameters)
|
||||||
INAPPLICABLE, // arguments have wrong types
|
INAPPLICABLE, // arguments have wrong types
|
||||||
INAPPLICABLE_MODIFIER, // no expected modifier (eg infix call on non-infix function)
|
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
|
IMPOSSIBLE_TO_GENERATE, // access to outer class from nested
|
||||||
RUNTIME_ERROR, // problems with visibility
|
RUNTIME_ERROR, // problems with visibility
|
||||||
UNSAFE_CALL, // receiver or argument nullability doesn't match
|
UNSAFE_CALL, // receiver or argument nullability doesn't match
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
package test
|
package test
|
||||||
|
|
||||||
import test.C.E1
|
import test.C.E1
|
||||||
@@ -17,7 +16,6 @@ class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
// Note: FIR resolve this to test/C instead of test/A.B.C
|
|
||||||
C
|
C
|
||||||
D()
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
||||||
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
||||||
|
|||||||
+6
@@ -24117,6 +24117,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
|
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
|
@Test
|
||||||
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
|
||||||
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
public void testResolveTypeArgsForUnresolvedCall() throws Exception {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
Resolved to:
|
Resolved to:
|
||||||
0: (in <local>: test) class Conflict
|
0: (in test.Conflict) companion object
|
||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
Resolved to:
|
Resolved to:
|
||||||
0: (in <local>: test) class Conflict
|
0: (in test) object Conflict
|
||||||
Reference in New Issue
Block a user