diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 1eef99131b1..3064dd43335 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -3292,6 +3292,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.DSL_SCOPE_VIOLATION) { firDiagnostic -> + DslScopeViolationImpl( + firSymbolBuilder.buildSymbol(firDiagnostic.a.fir), + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirErrors.TOPLEVEL_TYPEALIASES_ONLY) { firDiagnostic -> ToplevelTypealiasesOnlyImpl( firDiagnostic as FirPsiDiagnostic, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 81b1f597b7e..8f2c0b60bf0 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -2298,6 +2298,11 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val property: KtVariableSymbol } + abstract class DslScopeViolation : KtFirDiagnostic() { + override val diagnosticClass get() = DslScopeViolation::class + abstract val calleeSymbol: KtSymbol + } + abstract class ToplevelTypealiasesOnly : KtFirDiagnostic() { override val diagnosticClass get() = ToplevelTypealiasesOnly::class } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 65b0de8c1db..38abe2707f9 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -2767,6 +2767,12 @@ internal class PropertyAsOperatorImpl( override val token: ValidityToken, ) : KtFirDiagnostic.PropertyAsOperator(), KtAbstractFirDiagnostic +internal class DslScopeViolationImpl( + override val calleeSymbol: KtSymbol, + override val firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.DslScopeViolation(), KtAbstractFirDiagnostic + internal class ToplevelTypealiasesOnlyImpl( override val firDiagnostic: FirPsiDiagnostic, override val token: ValidityToken, diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index c4a00818364..07b64d98a6c 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -24532,6 +24532,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.kt"); } + @Test + @TestMetadata("typeAliasToBuiltinFunctionType.kt") + public void testTypeAliasToBuiltinFunctionType() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.kt"); + } + @Test @TestMetadata("unsupportedFeature.kt") public void testUnsupportedFeature() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index e52390f03be..fa79eece089 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -24532,6 +24532,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.kt"); } + @Test + @TestMetadata("typeAliasToBuiltinFunctionType.kt") + public void testTypeAliasToBuiltinFunctionType() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.kt"); + } + @Test @TestMetadata("unsupportedFeature.kt") public void testUnsupportedFeature() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 92e3fa10c29..59fd1f040e3 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -24532,6 +24532,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.kt"); } + @Test + @TestMetadata("typeAliasToBuiltinFunctionType.kt") + public void testTypeAliasToBuiltinFunctionType() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.kt"); + } + @Test @TestMetadata("unsupportedFeature.kt") public void testUnsupportedFeature() throws Exception { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 67d7253b8d5..a255bf02479 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -1191,6 +1191,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val PROPERTY_AS_OPERATOR by error(PositioningStrategy.OPERATOR) { parameter("property") } + val DSL_SCOPE_VIOLATION by error(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) { + parameter>("calleeSymbol") + } } val TYPE_ALIAS by object : DiagnosticGroup("Type alias") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 84e166bb8d6..7209f8b4923 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -623,6 +623,7 @@ object FirErrors { val INC_DEC_SHOULD_NOT_RETURN_UNIT by error0(SourceElementPositioningStrategies.OPERATOR) val ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT by error2(SourceElementPositioningStrategies.OPERATOR) val PROPERTY_AS_OPERATOR by error1(SourceElementPositioningStrategies.OPERATOR) + val DSL_SCOPE_VIOLATION by error1>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) // Type alias val TOPLEVEL_TYPEALIASES_ONLY by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 905e70a9e4c..2238f6027ed 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -146,6 +146,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_TYPE_P import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATION_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_ERROR +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DSL_SCOPE_VIOLATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DUPLICATE_LABEL_IN_WHEN import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DYNAMIC_UPPER_BOUND import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EMPTY_RANGE @@ -1611,6 +1612,12 @@ class FirDefaultErrorMessages { "Property ''{0}'' cannot be used as an operator.", SYMBOL ) + map.put( + DSL_SCOPE_VIOLATION, + "''{0}'' can''t be called in this context by implicit receiver. " + + "Use the explicit one if necessary", + SYMBOL + ) // Type alias map.put(TOPLEVEL_TYPEALIASES_ONLY, "Nested and local type aliases are not supported") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index b50fc4de1ba..6618cf08ddb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -225,6 +225,7 @@ private fun mapInapplicableCandidateError( rootCause.argument.smartcastStability.description, rootCause.isCastToNotNull ) + is DslScopeViolation -> FirErrors.DSL_SCOPE_VIOLATION.createOn(source, rootCause.calleeSymbol) else -> genericDiagnostic } }.distinct() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt index e0167acda33..e14c01e5268 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt @@ -16,6 +16,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) { CollectTypeVariableUsagesInfo, CheckDispatchReceiver, CheckExtensionReceiver, + CheckDslScopeViolation, CheckLowPriorityInOverloadResolution, PostponedVariablesInitializerResolutionStage, ) @@ -40,6 +41,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) { CollectTypeVariableUsagesInfo, CheckDispatchReceiver, CheckExtensionReceiver, + CheckDslScopeViolation, CheckArguments, CheckCallModifiers, EagerResolveOfCallableReferences, @@ -57,6 +59,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) { CollectTypeVariableUsagesInfo, CheckDispatchReceiver, CheckExtensionReceiver, + CheckDslScopeViolation, CheckArguments, EagerResolveOfCallableReferences, ) @@ -70,6 +73,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) { CollectTypeVariableUsagesInfo, CheckDispatchReceiver, CheckExtensionReceiver, + CheckDslScopeViolation, CheckCallableReferenceExpectedType, CheckLowPriorityInOverloadResolution, ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt index 69a6588c6e4..cc17389556e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerGroup import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.isSuccess +import org.jetbrains.kotlin.resolve.calls.tower.shouldStopResolve open class CandidateCollector( val components: BodyResolveComponents, @@ -48,7 +49,7 @@ open class CandidateCollector( fun bestCandidates(): List = candidates fun shouldStopAtTheLevel(group: TowerGroup): Boolean = - isSuccess() && bestGroup < group + currentApplicability.shouldStopResolve && bestGroup < group fun isSuccess(): Boolean { return currentApplicability.isSuccess diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt index 0fe15ee12a1..5b3c0e17416 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget @@ -102,4 +103,6 @@ class OperatorCallOfNonOperatorFunction(val function: FirNamedFunctionSymbol) : class Unsupported(val message: String, val source: FirSourceElement? = null) : ResolutionDiagnostic(UNSUPPORTED) -object PropertyAsOperator : ResolutionDiagnostic(PROPERTY_AS_OPERATOR) \ No newline at end of file +object PropertyAsOperator : ResolutionDiagnostic(PROPERTY_AS_OPERATOR) + +class DslScopeViolation(val calleeSymbol: FirBasedSymbol<*>) : ResolutionDiagnostic(DSL_SCOPE_VIOLATION) \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 9eb4a083fe2..f8c7162e2d5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -5,19 +5,19 @@ package org.jetbrains.kotlin.fir.resolve.calls -import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirVisibilityChecker import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.isInfix -import org.jetbrains.kotlin.fir.declarations.utils.isOperator -import org.jetbrains.kotlin.fir.declarations.utils.modality +import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirSuperReference +import org.jetbrains.kotlin.fir.resolve.directExpansionType +import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.inference.* import org.jetbrains.kotlin.fir.resolve.isTypeMismatchDueToNullability import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope +import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol @@ -32,8 +32,10 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.* import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability +import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue import org.jetbrains.kotlin.types.AbstractNullabilityChecker import org.jetbrains.kotlin.types.TypeApproximatorConfiguration +import org.jetbrains.kotlin.util.OperatorNameConventions abstract class ResolutionStage { abstract suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) @@ -104,6 +106,7 @@ object CheckExtensionReceiver : ResolutionStage() { } object CheckDispatchReceiver : ResolutionStage() { + @OptIn(SymbolInternals::class) override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { val explicitReceiverExpression = callInfo.explicitReceiver if (explicitReceiverExpression.isSuperCall()) { @@ -144,6 +147,152 @@ object CheckDispatchReceiver : ResolutionStage() { } } +/** + * See https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-dsl-marker/ for more details and + * /compiler/testData/diagnostics/tests/resolve/dslMarker for the test files. + */ +object CheckDslScopeViolation : ResolutionStage() { + private val dslMarkerClassId = ClassId.fromString("kotlin/DslMarker") + + @OptIn(ExperimentalStdlibApi::class) + override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { + fun checkReceiverValue(receiverValue: ReceiverValue?) { + if (receiverValue is ImplicitReceiverValue<*>) { + receiverValue.checkImpl( + candidate, + sink, + context, + { receiverValue.getDslMarkersOfImplicitReceiver(context) } + ) { a, b -> a == b } + } + } + checkReceiverValue(candidate.dispatchReceiverValue) + checkReceiverValue(candidate.extensionReceiverValue) + + // For value of builtin functional type with implicit extension receiver, the receiver is passed as the first argument rather than + // an extension receiver of the `invoke` call. Hence, we need to specially handle this case. + // For example, consider the following + // ``` + // @DslMarker + // annotation class MyDsl + // + // @MyDsl + // class X + // fun x(block: X.() -> Unit) {} + // + // @MyDsl + // class A + // fun a(block: A.() -> Unit) {} + // + // val useX: X.() -> Unit + // + // fun test() { + // x { + // a { + // useX() // DSL_SCOPE_VIOLATION because `useX` needs "extension receiver" `X`. + // } + // } + // } + // ``` + // `useX()` is a call to `invoke` with `useX` as the dispatch receiver. In the FIR tree, extension receiver is represented as an + // implicit `this` expression passed as the first argument. + if (candidate.dispatchReceiverValue?.type?.fullyExpandedType(context.session)?.isBuiltinFunctionalType(context.session) == true && + (candidate.symbol as? FirNamedFunctionSymbol)?.name == OperatorNameConventions.INVOKE + ) { + val firstArg = candidate.argumentMapping?.keys?.firstOrNull() as? FirThisReceiverExpression ?: return + if (firstArg.source != null) return // Having no source means it's implicit. + firstArg.checkImpl( + candidate, + sink, + context, + { firstArg.getDslMarkersOfThisReceiverExpression(context) } + ) { receiver, thisExpression -> receiver.boundSymbol == thisExpression.calleeReference.boundSymbol } + } + } + + /** + * Checks whether the implicit receiver (represented as an object of type `T`) violates DSL scope rules. + */ + private fun T.checkImpl( + candidate: Candidate, + sink: CheckerSink, + context: ResolutionContext, + dslMarkersProvider: () -> Set, + isImplicitReceiverMatching: (ImplicitReceiverValue<*>, T) -> Boolean, + ) { + val resolvedReceiverIndex = context.bodyResolveContext.implicitReceiverStack.indexOfFirst { isImplicitReceiverMatching(it, this) } + if (resolvedReceiverIndex == -1) return + val closerReceivers = context.bodyResolveContext.implicitReceiverStack.drop(resolvedReceiverIndex + 1) + if (closerReceivers.isEmpty()) return + val dslMarkers = dslMarkersProvider() + if (dslMarkers.isEmpty()) return + if (closerReceivers.any { receiver -> receiver.getDslMarkersOfImplicitReceiver(context).any { it in dslMarkers } }) { + sink.reportDiagnostic(DslScopeViolation(candidate.symbol)) + } + } + + @OptIn(ExperimentalStdlibApi::class) + private fun ImplicitReceiverValue<*>.getDslMarkersOfImplicitReceiver(context: ResolutionContext): Set { + return buildSet { + collectDslMarkerAnnotations(context, type) + } + } + + @OptIn(ExperimentalStdlibApi::class) + private fun FirThisReceiverExpression.getDslMarkersOfThisReceiverExpression(context: ResolutionContext): Set { + return buildSet { + collectDslMarkerAnnotations(context, typeRef.coneType) + } + } + + @OptIn(SymbolInternals::class) + private fun MutableSet.collectDslMarkerAnnotations(context: ResolutionContext, type: ConeKotlinType) { + collectDslMarkerAnnotations(context, type.attributes.customAnnotations) + when (type) { + is ConeFlexibleType -> { + collectDslMarkerAnnotations(context, type.lowerBound) + collectDslMarkerAnnotations(context, type.upperBound) + } + is ConeCapturedType -> { + if (type.constructor.projection.kind == ProjectionKind.OUT) { + type.constructor.supertypes?.forEach { collectDslMarkerAnnotations(context, it) } + } + } + is ConeDefinitelyNotNullType -> collectDslMarkerAnnotations(context, type.original) + is ConeIntersectionType -> type.intersectedTypes.forEach { collectDslMarkerAnnotations(context, it) } + is ConeLookupTagBasedType -> { + val classDeclaration = type.toSymbol(context.session)?.fir as? FirClassLikeDeclaration ?: return + collectDslMarkerAnnotations(context, classDeclaration.annotations) + when { + classDeclaration is FirClass -> { + for (superType in classDeclaration.superConeTypes) { + collectDslMarkerAnnotations(context, superType) + } + } + type is ConeClassLikeType -> { + type.directExpansionType(context.session)?.let { + collectDslMarkerAnnotations(context, it) + } + } + } + } + else -> return + } + } + + @OptIn(SymbolInternals::class) + private fun MutableSet.collectDslMarkerAnnotations(context: ResolutionContext, annotations: Collection) { + for (annotation in annotations) { + val annotationClass = + annotation.annotationTypeRef.coneType.fullyExpandedType(context.session).toSymbol(context.session)?.fir as? FirClass + ?: continue + if (annotationClass.hasAnnotation(dslMarkerClassId)) { + add(annotationClass.classId) + } + } + } +} + private fun FirExpression?.isSuperCall(): Boolean { if (this !is FirQualifiedAccessExpression) return false return calleeReference is FirSuperReference diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/tower/CandidateApplicability.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/tower/CandidateApplicability.kt index 4bd00a29203..36731392dd3 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/tower/CandidateApplicability.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/tower/CandidateApplicability.kt @@ -20,6 +20,11 @@ enum class CandidateApplicability { UNSAFE_CALL, // receiver or argument nullability doesn't match UNSTABLE_SMARTCAST, // unstable smart cast CONVENTION_ERROR, // missing infix, operator etc + + // Below has shouldStopResolve = true + DSL_SCOPE_VIOLATION, // Skip other levels for DSL_SCOPE_VIOLATION because if the candidate is marked DSL_SCOPE_VIOLATION with an inner receiver, one should not keep going to outer receivers. + + // Below has isSuccess = true RESOLVED_LOW_PRIORITY, PROPERTY_AS_OPERATOR, // using property of functional type as an operator. From resolution perspective, this is considered successful. RESOLVED_NEED_PRESERVE_COMPATIBILITY, // call resolved successfully, but using new features that changes resolve @@ -29,3 +34,6 @@ enum class CandidateApplicability { val CandidateApplicability.isSuccess: Boolean get() = this >= CandidateApplicability.RESOLVED_LOW_PRIORITY + +val CandidateApplicability.shouldStopResolve: Boolean + get() = this >= CandidateApplicability.DSL_SCOPE_VIOLATION diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedFunctionType.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedFunctionType.fir.kt index 7e9749c5768..cd70b96e197 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedFunctionType.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedFunctionType.fir.kt @@ -29,7 +29,7 @@ fun main() { baz1 { baz2 { bar() - foo() + foo() } } diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedFunctionType_1_4.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedFunctionType_1_4.fir.kt index ee9222f6e0e..3b1fd1ccbc2 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedFunctionType_1_4.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedFunctionType_1_4.fir.kt @@ -29,7 +29,7 @@ fun main() { baz1 { baz2 { bar() - foo() + foo() } } diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedTypeArgument.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedTypeArgument.fir.kt deleted file mode 100644 index 6821b6aa407..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedTypeArgument.fir.kt +++ /dev/null @@ -1,26 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -@Target(AnnotationTarget.TYPE) -annotation class Ann - -class A { - fun a() = 1 -} - -class B { - fun b() = 2 -} - -fun foo(x: T.() -> Unit) {} -fun bar(x: E.() -> Unit) {} - -fun test() { - foo<@Ann A> { - a() - bar<@Ann B> { - a() - this@foo.a() - b() - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedTypeArgument.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedTypeArgument.kt index 73574ec679f..75fe2181d7c 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedTypeArgument.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/annotatedTypeArgument.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker @Target(AnnotationTarget.TYPE) diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.fir.kt deleted file mode 100644 index b968e5bff83..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.fir.kt +++ /dev/null @@ -1,28 +0,0 @@ -@DslMarker -@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS) -annotation class XMarker - -@XMarker -class Foo - -class Bar - -@XMarker -typealias XBar = Bar - -typealias XXBar = XBar - -fun Foo.foo(body: Foo.() -> Unit) = body() -fun Foo.xbar(body: XBar.() -> Unit) = Bar().body() -fun Foo.xxbar(body: XXBar.() -> Unit) = Bar().body() - -fun test() { - Foo().foo { - xbar { - foo {} - } - xxbar { - foo {} - } - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.kt index 342509a4421..b5c5ba734f0 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL @DslMarker @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS) annotation class XMarker diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/inheritedMarker.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/inheritedMarker.fir.kt deleted file mode 100644 index 83a3ea54e79..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/inheritedMarker.fir.kt +++ /dev/null @@ -1,30 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -annotation class Ann - -@Ann -interface Common -interface C : Common -interface D : C - -class A : C { - fun a() = 1 -} - -class B : D { - fun b() = 2 -} - -fun foo(x: A.() -> Unit) {} -fun bar(x: B.() -> Unit) {} - -fun test() { - foo { - a() - bar { - a() - this@foo.a() - b() - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/inheritedMarker.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/inheritedMarker.kt index a216696fd21..28e3a58322e 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/inheritedMarker.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/inheritedMarker.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker annotation class Ann diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtension.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtension.fir.kt deleted file mode 100644 index bbed69f4773..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtension.fir.kt +++ /dev/null @@ -1,23 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -annotation class Ann - -@Ann -class A { - fun a() = 1 -} - -@Ann -class B { - fun b() = 2 -} - -fun bar(x: B.() -> Unit) {} - -fun A.test() { - bar { - a() - this@test.a() - b() - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtension.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtension.kt index 4be529bdfd8..3c82b18ccc0 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtension.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtension.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker annotation class Ann diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.fir.kt deleted file mode 100644 index dcdcd748b25..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.fir.kt +++ /dev/null @@ -1,22 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -@Target(AnnotationTarget.TYPE) -annotation class Ann - -class A { - fun a() = 1 -} - -class B { - fun b() = 2 -} - -fun bar(x: (@Ann B).() -> Unit) {} - -fun @Ann A.test() { - bar { - a() - this@test.a() - b() - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.kt index 9d95f874c89..e053354f3cb 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker @Target(AnnotationTarget.TYPE) diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/markersIntersection.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/markersIntersection.fir.kt index 8d2c9493f41..89f88f4c9d2 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/markersIntersection.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/markersIntersection.fir.kt @@ -29,12 +29,12 @@ fun test() { foo12 { a() bar1 { - a() + a() b() } bar2 { - a() + a() b() } } @@ -43,7 +43,7 @@ fun test() { b() foo12 { a() - b() + b() } } @@ -51,7 +51,7 @@ fun test() { b() foo12 { a() - b() + b() } } @@ -64,7 +64,7 @@ fun test() { } bar2 { - a() + a() b() } } @@ -85,7 +85,7 @@ fun test() { foo2 { bar1t(this) { a() - b() + b() } } } diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/nestedWithSameReceiver.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/nestedWithSameReceiver.fir.kt deleted file mode 100644 index 9e08430d307..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/nestedWithSameReceiver.fir.kt +++ /dev/null @@ -1,40 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -@Target(AnnotationTarget.TYPE) -annotation class Ann - -class A { - fun a() = 1 -} - -class B { - fun b() = 2 -} - -fun foo(x: (@Ann A).() -> Unit) {} -fun bar(x: (@Ann B).() -> Unit) {} - -fun test() { - foo { - a() - foo l1@{ - a() - bar l2@{ - a() - this@l1.a() - b() - - foo l3@{ - a() - b() - this@l2.b() - bar { - a() - this@l3.a() - b() - } - } - } - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/nestedWithSameReceiver.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/nestedWithSameReceiver.kt index 8ff6db728d6..61e1fc0b941 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/nestedWithSameReceiver.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/nestedWithSameReceiver.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker @Target(AnnotationTarget.TYPE) diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/properties.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/properties.fir.kt index 2c75099988a..783d60abfc2 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/properties.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/properties.fir.kt @@ -34,13 +34,13 @@ fun test() { a1++ bar { - a + 1 - a += a + 1 - a++ + a + 1 + a += a + 1 + a++ - a1 + 1 - a1 += a1 + 1 - a1++ + a1 + 1 + a1 += a1 + 1 + a1++ this@foo.a + 1 this@foo.a += this@foo.a + 1 diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedClasses.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedClasses.kt index 5add0eb24ff..03b8733a1a0 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedClasses.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedClasses.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker annotation class Ann diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedTypes.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedTypes.fir.kt deleted file mode 100644 index 5603ec6df14..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedTypes.fir.kt +++ /dev/null @@ -1,26 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -@Target(AnnotationTarget.TYPE) -annotation class Ann - -class A { - fun a() = 1 -} - -class B { - fun b() = 2 -} - -fun foo(x: (@Ann A).() -> Unit) {} -fun bar(x: (@Ann B).() -> Unit) {} - -fun test() { - foo { - a() - bar { - a() - this@foo.a() - b() - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedTypes.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedTypes.kt index 71723513db6..4a34122ea9d 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedTypes.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedTypes.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker @Target(AnnotationTarget.TYPE) diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/substitutedReceiverAnnotatedClasses.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/substitutedReceiverAnnotatedClasses.fir.kt deleted file mode 100644 index 24d4eb3e602..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/substitutedReceiverAnnotatedClasses.fir.kt +++ /dev/null @@ -1,27 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -annotation class Ann - -@Ann -class A { - fun a() = 1 -} - -@Ann -class B { - fun b() = 2 -} - -fun foo(x: T.() -> Unit) {} -fun bar(x: E.() -> Unit) {} - -fun test() { - foo { - a() - bar { - a() - this@foo.a() - b() - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/substitutedReceiverAnnotatedClasses.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/substitutedReceiverAnnotatedClasses.kt index 558522df35a..931927eadc1 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/substitutedReceiverAnnotatedClasses.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/substitutedReceiverAnnotatedClasses.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker annotation class Ann diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers.fir.kt index 8f9da99c879..0ef35e9e238 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers.fir.kt @@ -48,8 +48,8 @@ fun test() { D().x() foo1 { - x() - y() + x() + y() with(A()) { x() @@ -57,19 +57,19 @@ fun test() { } with(D()) { - x() + x() } - D().x() + D().x() } foo2 { x() - y() + y() } foo3 { - x() - y() + x() + y() } } } @@ -79,7 +79,7 @@ fun test() { foo { baz { bar { - x() + x() y() } } @@ -90,7 +90,7 @@ fun test() { foo { baz { bar { - x() + x() y() } } @@ -101,7 +101,7 @@ fun test() { foo { baz { bar { - x() + x() y() } } diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers2.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers2.fir.kt index 8ef8b0966d7..1eb796edb02 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers2.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers2.fir.kt @@ -43,8 +43,8 @@ fun test() { } foo1 { - x() - y() + x() + y() with(A()) { x() @@ -52,19 +52,19 @@ fun test() { } with(D()) { - x() + x() } A().x() } foo2 { x() - y() + y() } foo3 { - x() - y() + x() + y() } } } @@ -74,7 +74,7 @@ fun test() { foo { baz { bar { - x() + x() y() } } @@ -85,7 +85,7 @@ fun test() { foo { baz { bar { - x() + x() y() } } @@ -96,7 +96,7 @@ fun test() { foo { baz { bar { - x() + x() y() } } diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/twoImplicitReceivers.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/twoImplicitReceivers.fir.kt deleted file mode 100644 index 6d1cff02306..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/twoImplicitReceivers.fir.kt +++ /dev/null @@ -1,102 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -@Target(AnnotationTarget.TYPE) -annotation class Ann1 - -@DslMarker -@Target(AnnotationTarget.TYPE) -annotation class Ann2 - -class A { - fun D.extA() {} -} - -class B { - fun D.extB() {} -} - -class D - -fun foo(x: (@Ann1 A).() -> Unit) {} -fun bar(x: (@Ann2 B).() -> Unit) {} -fun baz(x: (@Ann1 D).() -> Unit) {} - -fun test() { - foo { - bar { - baz { - extA() - extB() - - D().extA() - D().extB() - - with(D()) { - extA() - extB() - } - } - } - } - - foo { - baz { - extA() - D().extA() - - bar { - extA() - extB() - - D().extA() - D().extB() - - with(D()) { - extA() - extB() - } - } - } - } - - baz { - foo { - extA() - D().extA() - - bar { - extA() - extB() - - D().extA() - D().extB() - - with(D()) { - extA() - extB() - } - } - } - } - - baz { - bar { - extB() - - D().extB() - - foo { - extA() - extB() - - D().extA() - D().extB() - - with(D()) { - extA() - extB() - } - } - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/twoImplicitReceivers.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/twoImplicitReceivers.kt index d171b106c92..8cde8e3322b 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/twoImplicitReceivers.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/twoImplicitReceivers.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker @Target(AnnotationTarget.TYPE) diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.fir.kt deleted file mode 100644 index dded7a3c332..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.fir.kt +++ /dev/null @@ -1,104 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -@Target(AnnotationTarget.TYPE) -annotation class L1 - -@DslMarker -@Target(AnnotationTarget.TYPE) -annotation class L2 - -class A { - fun a() = 1 -} - -class B { - fun b() = 2 -} - -fun foo1(x: (@L1 A).() -> Unit) {} -fun foo2(x: (@L2 A).() -> Unit) {} -fun bar1(x: (@L1 B).() -> Unit) {} -fun bar2(x: (@L2 B).() -> Unit) {} - -fun test() { - foo1 { - a() - - foo2 { - a() - - bar1 { - a() - b() - bar2 { - a() - b() - } - } - - bar2 { - a() - b() - } - } - - bar1 { - a() - b() - bar2 { - a() - b() - } - } - - bar2 { - a() - b() - } - } - - foo2 { - a() - - bar1 { - a() - b() - bar2 { - a() - b() - } - } - - bar2 { - a() - b() - } - } - - bar1 { - b() - bar2 { - b() - } - } - - bar2 { - b() - } - - foo1 { - bar1 { - a() - b() - foo2 { - a() - b() - - bar2 { - a() - b() - } - } - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.kt index 0d6dfbe44ae..b0a3dbc7870 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker @Target(AnnotationTarget.TYPE) diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.kt new file mode 100644 index 00000000000..1845499cb77 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.kt @@ -0,0 +1,28 @@ +// FIR_IDENTICAL +@DslMarker +annotation class MyDsl + +@MyDsl +class X + +fun x(block: X.() -> Unit) {} + +@MyDsl +class A + +fun a(block: A.() -> Unit) {} + +val useX1: X.() -> Unit = TODO() +typealias FunctionType = X.() -> Unit + +val useX2: FunctionType = TODO() + + +fun test() { + x { + a { + useX1() + useX2() + } + } +} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.txt b/compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.txt new file mode 100644 index 00000000000..d9e60edae0c --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.txt @@ -0,0 +1,29 @@ +package + +public val useX1: X.() -> kotlin.Unit +public val useX2: FunctionType /* = X.() -> kotlin.Unit */ +public fun a(/*0*/ block: A.() -> kotlin.Unit): kotlin.Unit +public fun test(): kotlin.Unit +public fun x(/*0*/ block: X.() -> kotlin.Unit): kotlin.Unit + +@MyDsl public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.DslMarker public final annotation class MyDsl : kotlin.Annotation { + public constructor MyDsl() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@MyDsl public final class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} +public typealias FunctionType = X.() -> kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedClasses.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/unsupportedFeature.fir.kt similarity index 80% rename from compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedClasses.fir.kt rename to compiler/testData/diagnostics/tests/resolve/dslMarker/unsupportedFeature.fir.kt index dd96e9a7fd4..1ad3b745272 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/simpleAnnotatedClasses.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/unsupportedFeature.fir.kt @@ -1,3 +1,4 @@ +// !LANGUAGE: -DslMarkersSupport // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker annotation class Ann @@ -19,7 +20,7 @@ fun test() { foo { a() bar { - a() + a() this@foo.a() b() } diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/unsupportedFeature.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/unsupportedFeature.kt index 4c2242ead75..e67767e06d7 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/unsupportedFeature.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/unsupportedFeature.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // !LANGUAGE: -DslMarkersSupport // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/useOfExtensions.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/useOfExtensions.fir.kt deleted file mode 100644 index 67f3907fd21..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/useOfExtensions.fir.kt +++ /dev/null @@ -1,27 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -annotation class Ann - -@Ann -class A - -fun A.a() = 1 - -@Ann -class B - -fun B.b() = 2 - -fun foo(x: A.() -> Unit) {} -fun bar(x: B.() -> Unit) {} - -fun test() { - foo { - a() - bar { - a() - this@foo.a() - b() - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/useOfExtensions.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/useOfExtensions.kt index 124d69b2eb2..ea16a23cb10 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/useOfExtensions.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/useOfExtensions.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker annotation class Ann diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWith.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWith.fir.kt deleted file mode 100644 index 657f48d8e9c..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWith.fir.kt +++ /dev/null @@ -1,24 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -annotation class Ann - -@Ann -class A { - fun a() = 1 -} - -@Ann -class B { - fun b() = 2 -} - -fun test(a: A, b: B) { - with(a) l1@{ - a() - with(b) { - a() - this@l1.a() - b() - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWith.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWith.kt index 40a62297a5f..7bebdadc3ce 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWith.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWith.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker annotation class Ann diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWithThis.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWithThis.fir.kt deleted file mode 100644 index 91967af6ae4..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWithThis.fir.kt +++ /dev/null @@ -1,30 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -@DslMarker -@Target(AnnotationTarget.TYPE) -annotation class Ann - -class A { - fun a() = 1 -} - -class B { - fun b() = 2 -} - -fun foo(x: (@Ann A).() -> Unit) {} -fun bar(x: (@Ann B).() -> Unit) {} - -fun test() { - foo { - with(this) l1@{ - a() - bar { - with(this) { - a() - this@l1.a() - b() - } - } - } - } -} diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWithThis.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWithThis.kt index 5fa725d5bc8..cadeb61f606 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWithThis.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/usingWithThis.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER @DslMarker @Target(AnnotationTarget.TYPE) diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 57692385ea5..60b2b361c73 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -24544,6 +24544,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/twoLanguages.kt"); } + @Test + @TestMetadata("typeAliasToBuiltinFunctionType.kt") + public void testTypeAliasToBuiltinFunctionType() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/typeAliasToBuiltinFunctionType.kt"); + } + @Test @TestMetadata("unsupportedFeature.kt") public void testUnsupportedFeature() throws Exception {