diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DslScopeViolationCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DslScopeViolationCallChecker.kt index e3e7d568714..9300689a57c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DslScopeViolationCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DslScopeViolationCallChecker.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.diagnostics.Errors @@ -30,6 +31,9 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.getAbbreviation +import org.jetbrains.kotlin.utils.addToStdlib.cast +import org.jetbrains.kotlin.utils.addToStdlib.safeAs object DslScopeViolationCallChecker : CallChecker { override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { @@ -71,6 +75,13 @@ object DslScopeViolationCallChecker : CallChecker { result.addAll(annotations.extractDslMarkerFqNames()) + getAbbreviation()?.constructor?.declarationDescriptor?.run { + result.addAll(annotations.extractDslMarkerFqNames()) + safeAs()?.run { + result.addAll(underlyingType.extractDslMarkerFqNames()) + } + } + constructor.declarationDescriptor?.getAllSuperClassifiers()?.asIterable() ?.flatMapTo(result) { it.annotations.extractDslMarkerFqNames() } diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.kt new file mode 100644 index 00000000000..342509a4421 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.kt @@ -0,0 +1,28 @@ +@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.txt b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.txt new file mode 100644 index 00000000000..d5361fc3bce --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.txt @@ -0,0 +1,29 @@ +package + +public fun test(): kotlin.Unit +public fun Foo.foo(/*0*/ body: Foo.() -> kotlin.Unit): kotlin.Unit +public fun Foo.xbar(/*0*/ body: XBar /* = Bar */.() -> kotlin.Unit): kotlin.Unit +public fun Foo.xxbar(/*0*/ body: XXBar /* = Bar */.() -> kotlin.Unit): kotlin.Unit + +public final class Bar { + public constructor Bar() + 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 +} + +@XMarker public final class Foo { + public constructor Foo() + 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 @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS}) public final annotation class XMarker : kotlin.Annotation { + public constructor XMarker() + 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 +} +@XMarker public typealias XBar = Bar +public typealias XXBar = XBar diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerWithTypealiasRecursion.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerWithTypealiasRecursion.kt new file mode 100644 index 00000000000..1fb93f4ea9f --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerWithTypealiasRecursion.kt @@ -0,0 +1,22 @@ +@DslMarker +@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS) +annotation class XMarker + +@XMarker +class Foo + +class Bar + +typealias YBar = ZBar +typealias ZBar = YBar + +fun Foo.foo(body: Foo.() -> Unit) = body() +fun Foo.zbar(body: ZBar.() -> Unit) = Bar().body() + +fun test() { + Foo().foo { + zbar { + foo {} + } + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerWithTypealiasRecursion.txt b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerWithTypealiasRecursion.txt new file mode 100644 index 00000000000..f950d8a0556 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerWithTypealiasRecursion.txt @@ -0,0 +1,28 @@ +package + +public fun test(): kotlin.Unit +public fun Foo.foo(/*0*/ body: Foo.() -> kotlin.Unit): kotlin.Unit +public fun Foo.zbar(/*0*/ body: [ERROR : Recursive type alias: ZBar].() -> kotlin.Unit): [ERROR : Error function type] + +public final class Bar { + public constructor Bar() + 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 +} + +@XMarker public final class Foo { + public constructor Foo() + 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 @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS}) public final annotation class XMarker : kotlin.Annotation { + public constructor XMarker() + 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 YBar = ZBar +public typealias ZBar = YBar diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index efa1ac71357..42dd94c9217 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -17595,6 +17595,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("dslMarkerOnTypealias.kt") + public void testDslMarkerOnTypealias() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerOnTypealias.kt"); + doTest(fileName); + } + + @TestMetadata("dslMarkerWithTypealiasRecursion.kt") + public void testDslMarkerWithTypealiasRecursion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/dslMarker/dslMarkerWithTypealiasRecursion.kt"); + doTest(fileName); + } + @TestMetadata("inheritedMarker.kt") public void testInheritedMarker() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/dslMarker/inheritedMarker.kt");