diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt index 3d9c85f8769..c0d649a890f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt @@ -162,6 +162,7 @@ object CommonExpressionCheckers : ExpressionCheckers() { override val resolvedQualifierCheckers: Set get() = setOf( FirStandaloneQualifierChecker, + FirPackageOnLhsQualifierChecker, FirOptInUsageQualifierChecker, FirDeprecatedQualifierChecker, FirVisibilityQualifierChecker, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirPackageOnLhsQualifierChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirPackageOnLhsQualifierChecker.kt new file mode 100644 index 00000000000..4784297cedc --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirPackageOnLhsQualifierChecker.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.expression + +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.diagnostics.reportOn +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess +import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier + +object FirPackageOnLhsQualifierChecker : FirResolvedQualifierChecker() { + override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) { + // Check that the expression is a package qualifier + if (expression.symbol != null) return + + // Left-Hand Side check + val lastCallableReferenceAccess = context.callsOrAssignments.lastOrNull() as? FirCallableReferenceAccess + val lastGetClass = context.getClassCalls.lastOrNull() + if (lastCallableReferenceAccess?.explicitReceiver !== expression && lastGetClass?.argument !== expression) return + + reporter.reportOn(expression.source, FirErrors.EXPRESSION_EXPECTED_PACKAGE_FOUND, context) + } +} diff --git a/compiler/testData/diagnostics/tests/callableReference/packageInLhs.fir.kt b/compiler/testData/diagnostics/tests/callableReference/packageInLhs.fir.kt index 9a280b8ae57..594180b5139 100644 --- a/compiler/testData/diagnostics/tests/callableReference/packageInLhs.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/packageInLhs.fir.kt @@ -4,7 +4,8 @@ package foo fun test() { - foo::test + foo::test + foo::class } // FILE: qualifiedName.kt @@ -12,5 +13,6 @@ fun test() { package foo.bar fun test() { - foo.bar::test + foo.bar::test + foo.bar::class } diff --git a/compiler/testData/diagnostics/tests/callableReference/packageInLhs.kt b/compiler/testData/diagnostics/tests/callableReference/packageInLhs.kt index 69c0ccba288..da13149cc2e 100644 --- a/compiler/testData/diagnostics/tests/callableReference/packageInLhs.kt +++ b/compiler/testData/diagnostics/tests/callableReference/packageInLhs.kt @@ -5,6 +5,7 @@ package foo fun test() { foo::test + foo::class } // FILE: qualifiedName.kt @@ -13,4 +14,5 @@ package foo.bar fun test() { foo.bar::test + foo.bar::class }