K2 JVM: implement Java modules-related checkers

All existing tests use custom test data for FIR because the diagnostic
text in FIR has to have a dot at the end. Also, the K2 checker doesn't
check usages in imports because there are no "import checkers" in K2
right now, this will need to be fixed later if necessary.

 #KT-60797 Fixed
This commit is contained in:
Alexander Udalov
2024-02-15 12:50:41 +01:00
committed by Space Team
parent ac901c6d07
commit 5ca7ab9801
23 changed files with 343 additions and 38 deletions
@@ -5390,6 +5390,27 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirJvmErrors.JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE) { firDiagnostic ->
JavaModuleDoesNotDependOnModuleImpl(
firDiagnostic.a,
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirJvmErrors.JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE) { firDiagnostic ->
JavaModuleDoesNotReadUnnamedModuleImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirJvmErrors.JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE) { firDiagnostic ->
JavaModuleDoesNotExportPackageImpl(
firDiagnostic.a,
firDiagnostic.b,
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirJvmErrors.JVM_DEFAULT_IN_DECLARATION) { firDiagnostic ->
JvmDefaultInDeclarationImpl(
firDiagnostic.a,
@@ -3751,6 +3751,21 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = IllegalJavaLangRecordSupertype::class
}
interface JavaModuleDoesNotDependOnModule : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = JavaModuleDoesNotDependOnModule::class
val moduleName: String
}
interface JavaModuleDoesNotReadUnnamedModule : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = JavaModuleDoesNotReadUnnamedModule::class
}
interface JavaModuleDoesNotExportPackage : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = JavaModuleDoesNotExportPackage::class
val moduleName: String
val packageName: String
}
interface JvmDefaultInDeclaration : KtFirDiagnostic<KtElement> {
override val diagnosticClass get() = JvmDefaultInDeclaration::class
val annotation: String
@@ -4528,6 +4528,24 @@ internal class IllegalJavaLangRecordSupertypeImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.IllegalJavaLangRecordSupertype
internal class JavaModuleDoesNotDependOnModuleImpl(
override val moduleName: String,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.JavaModuleDoesNotDependOnModule
internal class JavaModuleDoesNotReadUnnamedModuleImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.JavaModuleDoesNotReadUnnamedModule
internal class JavaModuleDoesNotExportPackageImpl(
override val moduleName: String,
override val packageName: String,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.JavaModuleDoesNotExportPackage
internal class JvmDefaultInDeclarationImpl(
override val annotation: String,
firDiagnostic: KtPsiDiagnostic,
@@ -7,20 +7,16 @@ package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageFeature.*
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.util.PrivateForInline
@Suppress("ClassName", "unused")
@@ -135,6 +131,17 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
val ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE by error<PsiElement>()
}
val MODULES by object : DiagnosticGroup("JVM Modules") {
val JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE by error<PsiElement> {
parameter<String>("moduleName")
}
val JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE by error<PsiElement>()
val JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE by error<PsiElement>() {
parameter<String>("moduleName")
parameter<String>("packageName")
}
}
val JVM_DEFAULT by object : DiagnosticGroup("JVM Default") {
val JVM_DEFAULT_IN_DECLARATION by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
parameter<String>("annotation")
@@ -99,6 +99,11 @@ object FirJvmErrors {
val JVM_RECORD_EXTENDS_CLASS: KtDiagnosticFactory1<ConeKotlinType> by error1<PsiElement, ConeKotlinType>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
val ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE: KtDiagnosticFactory0 by error0<PsiElement>()
// JVM Modules
val JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE: KtDiagnosticFactory1<String> by error1<PsiElement, String>()
val JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE: KtDiagnosticFactory0 by error0<PsiElement>()
val JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE: KtDiagnosticFactory2<String, String> by error2<PsiElement, String, String>()
// JVM Default
val JVM_DEFAULT_IN_DECLARATION: KtDiagnosticFactory1<String> by error1<KtElement, String>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION: KtDiagnosticFactory0 by error0<KtElement>()
@@ -34,6 +34,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INAPPLICAB
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INAPPLICABLE_JVM_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INNER_JVM_RECORD
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INTERFACE_CANT_CALL_DEFAULT_METHOD_VIA_SUPER
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JAVA_SAM_INTERFACE_CONSTRUCTOR_REFERENCE
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JAVA_TYPE_MISMATCH
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_IN_DECLARATION
@@ -182,6 +185,19 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
map.put(NON_DATA_CLASS_JVM_RECORD, "Only data classes are allowed to be marked as '@JvmRecord'.")
map.put(ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE, "Classes cannot have explicit 'java.lang.Record' supertype.")
map.put(
JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE,
"Symbol is declared in module ''{0}'', which the current module does not depend on.", STRING,
)
map.put(
JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE,
"Symbol is declared in an unnamed module which is not read by current module."
)
map.put(
JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE,
"Symbol is declared in module ''{0}'' which does not export package ''{1}''.", STRING, STRING,
)
map.put(OVERRIDE_CANNOT_BE_STATIC, "Override member cannot be '@JvmStatic' in an object.")
map.put(
JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION,
@@ -20,6 +20,7 @@ object JvmExpressionCheckers : ExpressionCheckers() {
FirInterfaceDefaultMethodCallChecker,
FirJavaSamInterfaceConstructorReferenceChecker,
FirQualifiedAccessJavaNullabilityWarningChecker,
FirJvmModuleAccessibilityQualifiedAccessChecker,
)
override val propertyAccessExpressionCheckers: Set<FirPropertyAccessExpressionChecker>
@@ -82,4 +83,9 @@ object JvmExpressionCheckers : ExpressionCheckers() {
get() = setOf(
FirJavaUnnecessaryNotNullChecker,
)
override val resolvedQualifierCheckers: Set<FirResolvedQualifierChecker>
get() = setOf(
FirJvmModuleAccessibilityResolvedQualifierChecker,
)
}
@@ -7,10 +7,12 @@ package org.jetbrains.kotlin.fir.analysis.jvm.checkers
import org.jetbrains.kotlin.fir.analysis.checkers.type.*
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.type.FirFunctionalTypeParameterNameChecker
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.type.FirJvmModuleAccessibilityTypeChecker
object JvmTypeCheckers : TypeCheckers() {
override val typeRefCheckers: Set<FirTypeRefChecker> = setOf(
FirDynamicUnsupportedChecker,
FirFunctionalTypeParameterNameChecker,
FirJvmModuleAccessibilityTypeChecker,
)
}
@@ -0,0 +1,93 @@
/*
* Copyright 2010-2023 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.jvm.checkers.expression
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.KtVirtualFileSourceFile
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.utils.sourceElement
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.toReference
import org.jetbrains.kotlin.fir.java.JavaBinarySourceElement
import org.jetbrains.kotlin.fir.modules.javaModuleResolverProvider
import org.jetbrains.kotlin.fir.packageFqName
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
object FirJvmModuleAccessibilityQualifiedAccessChecker : FirQualifiedAccessExpressionChecker(MppCheckerKind.Common) {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val callableSymbol = expression.calleeReference.toResolvedCallableSymbol() ?: return
if (callableSymbol.origin.fromSource) return
val containingClass = callableSymbol.containingClassLookupTag()
if (containingClass != null) {
val containingClassSymbol = containingClass.toFirRegularClassSymbol(context.session) ?: return
checkClassAccess(context, containingClassSymbol, expression, reporter)
} else {
val containerSource = callableSymbol.containerSource as? JvmPackagePartSource ?: return
val virtualFile = (containerSource.knownJvmBinaryClass as? VirtualFileKotlinClass)?.file ?: return
checkPackageAccess(context, virtualFile, containerSource.className.packageFqName, expression, reporter)
}
}
internal fun checkClassAccess(context: CheckerContext, symbol: FirClassSymbol<*>, element: FirElement, reporter: DiagnosticReporter) {
if (symbol.origin.fromSource) return
@OptIn(SymbolInternals::class)
val sourceElement = symbol.fir.sourceElement
val virtualFile = when (sourceElement) {
is JavaBinarySourceElement -> sourceElement.virtualFile
is KotlinJvmBinarySourceElement -> (sourceElement.binaryClass as? VirtualFileKotlinClass)?.file ?: return
else -> return
}
checkPackageAccess(context, virtualFile, symbol.packageFqName(), element, reporter)
}
internal fun checkPackageAccess(
context: CheckerContext,
fileFromPackage: VirtualFile,
referencedPackageFqName: FqName,
element: FirElement,
reporter: DiagnosticReporter,
) {
val fileFromOurModule = (context.containingFile?.sourceFile as? KtVirtualFileSourceFile)?.virtualFile
val diagnostic = context.session.javaModuleResolverProvider.javaModuleResolver.checkAccessibility(
fileFromOurModule, fileFromPackage, referencedPackageFqName
) ?: return
val source = element.toReference(context.session)?.source ?: element.source
when (diagnostic) {
is JavaModuleResolver.AccessError.ModuleDoesNotExportPackage -> {
reporter.reportOn(
source, FirJvmErrors.JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE, diagnostic.dependencyModuleName,
referencedPackageFqName.asString(), context,
)
}
is JavaModuleResolver.AccessError.ModuleDoesNotReadModule -> {
reporter.reportOn(source, FirJvmErrors.JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE, diagnostic.dependencyModuleName, context)
}
JavaModuleResolver.AccessError.ModuleDoesNotReadUnnamedModule -> {
reporter.reportOn(source, FirJvmErrors.JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE, context)
}
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2024 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.jvm.checkers.expression
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirResolvedQualifierChecker
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
object FirJvmModuleAccessibilityResolvedQualifierChecker : FirResolvedQualifierChecker(MppCheckerKind.Common) {
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
val symbol = expression.symbol
if (symbol is FirClassSymbol<*>) {
FirJvmModuleAccessibilityQualifiedAccessChecker.checkClassAccess(context, symbol, expression, reporter)
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2024 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.jvm.checkers.type
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.type.FirTypeRefChecker
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.FirJvmModuleAccessibilityQualifiedAccessChecker
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
object FirJvmModuleAccessibilityTypeChecker : FirTypeRefChecker(MppCheckerKind.Common) {
override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) {
val classSymbol = typeRef.coneTypeOrNull?.toRegularClassSymbol(context.session) ?: return
FirJvmModuleAccessibilityQualifiedAccessChecker.checkClassAccess(context, classSymbol, typeRef, reporter)
}
}
@@ -616,6 +616,9 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
"DELEGATION_BY_IN_JVM_RECORD",
"JVM_RECORD_EXTENDS_CLASS",
"ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE",
"JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE",
"JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE",
"JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE",
"JVM_DEFAULT_IN_DECLARATION",
"JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION",
"JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE",
@@ -23,11 +23,7 @@ import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmInlineCheckerCompone
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
import org.jetbrains.kotlin.fir.caches.FirThreadUnsafeCachesFactory
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOverloadabilityHelper
import org.jetbrains.kotlin.fir.declarations.FirTypeSpecificityComparatorProvider
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProviderImpl
import org.jetbrains.kotlin.fir.declarations.FirAnnotationsPlatformSpecificSupportComponent
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationExtension
import org.jetbrains.kotlin.fir.extensions.*
import org.jetbrains.kotlin.fir.java.FirJavaVisibilityChecker
@@ -39,6 +35,7 @@ import org.jetbrains.kotlin.fir.java.enhancement.FirAnnotationTypeQualifierResol
import org.jetbrains.kotlin.fir.java.enhancement.FirEnhancedSymbolsStorage
import org.jetbrains.kotlin.fir.java.enhancement.JavaCompilerRequiredAnnotationEnhancementProvider
import org.jetbrains.kotlin.fir.java.scopes.JavaOverridabilityRules
import org.jetbrains.kotlin.fir.modules.FirJavaModuleResolverProvider
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.calls.FirDeclarationOverloadabilityHelperImpl
@@ -133,6 +130,7 @@ fun FirSession.registerJavaComponents(
javaModuleResolver: JavaModuleResolver,
predefinedComponents: FirSharableJavaComponents? = null,
) {
register(FirJavaModuleResolverProvider::class, FirJavaModuleResolverProvider(javaModuleResolver))
val jsr305State = languageVersionSettings.getFlag(JvmAnalysisFlags.javaTypeEnhancementState)
register(
FirAnnotationTypeQualifierResolver::class,
@@ -5,10 +5,14 @@
package org.jetbrains.kotlin.fir.java
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
class JavaBinarySourceElement(val javaClass: BinaryJavaClass) : SourceElement {
val virtualFile: VirtualFile
get() = javaClass.virtualFile
override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE
}
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2024 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.modules
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
class FirJavaModuleResolverProvider(val javaModuleResolver: JavaModuleResolver) : FirSessionComponent
val FirSession.javaModuleResolverProvider: FirJavaModuleResolverProvider by FirSession.sessionComponentAccessor()
@@ -0,0 +1,4 @@
compiler/testData/javaModules/automaticModuleInternalJdkPackageUsage/jvmStatUsage/Test.kt:1:8: error: symbol is declared in module 'jdk.internal.jvmstat' which does not export package 'sun.jvmstat.monitor'.
val z: sun.jvmstat.monitor.Monitor? = null
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
COMPILATION_ERROR
@@ -0,0 +1,13 @@
compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt:3:15: error: symbol is declared in module 'lib', which the current module does not depend on.
fun test(foo: Foo) {
^^^
compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt:4:9: error: symbol is declared in module 'lib', which the current module does not depend on.
foo.field
^^^^^
compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt:5:9: error: symbol is declared in module 'lib', which the current module does not depend on.
foo.method()
^^^^^^
compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt:6:5: error: symbol is declared in module 'lib', which the current module does not depend on.
Foo()
^^^
COMPILATION_ERROR
@@ -0,0 +1,13 @@
compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt:3:15: error: symbol is declared in an unnamed module which is not read by current module.
fun test(foo: Foo) {
^^^
compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt:4:9: error: symbol is declared in an unnamed module which is not read by current module.
foo.field
^^^^^
compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt:5:9: error: symbol is declared in an unnamed module which is not read by current module.
foo.method()
^^^^^^
compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt:6:5: error: symbol is declared in an unnamed module which is not read by current module.
Foo()
^^^
COMPILATION_ERROR
@@ -0,0 +1,37 @@
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:8:9: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val a3: AImpl = A.getInstance()
^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:9:18: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val a4: String = AImpl.method()
^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:9:24: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val a4: String = AImpl.method()
^^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:10:18: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val a5: String = AImpl.field
^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:10:24: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val a5: String = AImpl.field
^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:14:9: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val k3: KImpl = K.getInstance()
^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:15:18: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val k4: String = KImpl.method()
^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:15:24: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val k4: String = KImpl.method()
^^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:16:18: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val k5: String = KImpl.field
^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:16:24: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val k5: String = KImpl.field
^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:18:19: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val kf1: String = fileField
^^^^^^^^^
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:19:19: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'.
val kf2: String = fileMethod()
^^^^^^^^^^
COMPILATION_ERROR
@@ -0,0 +1,7 @@
compiler/testData/javaModules/specifyPathToModuleInfoInArguments/moduleB/usage.kt:9:5: error: symbol is declared in module 'moduleA' which does not export package 'unexported'.
Unexported()
^^^^^^^^^^
compiler/testData/javaModules/specifyPathToModuleInfoInArguments/moduleB/usage.kt:13:5: error: unresolved reference 'Unrelated'.
Unrelated()
^^^^^^^^^
COMPILATION_ERROR
@@ -0,0 +1,4 @@
compiler/testData/javaModules/unnamedDependsOnNamed/moduleB/usage.kt:7:5: error: symbol is declared in module 'moduleA' which does not export package 'foo.impl'.
Impl() // should be error
^^^^
COMPILATION_ERROR
@@ -9,14 +9,5 @@ import org.jetbrains.kotlin.config.LanguageVersion
import java.io.File
abstract class AbstractFirJavaModulesIntegrationTest(jdkVersion: Int, jdkHome: File) : AbstractJavaModulesIntegrationTest(
jdkVersion, jdkHome, maxOf(LanguageVersion.KOTLIN_2_0, LanguageVersion.LATEST_STABLE),
) {
override fun muteForK2(test: () -> Unit) {
try {
test()
} catch (e: Throwable) {
return
}
fail("Looks like this test can be unmuted. Remove the call to `muteForK2`.")
}
}
jdkVersion, jdkHome, LanguageVersion.LATEST_STABLE,
)
@@ -25,10 +25,6 @@ abstract class AbstractJavaModulesIntegrationTest(
override val testDataPath: String
get() = "compiler/testData/javaModules/"
protected open fun muteForK2(test: () -> Unit) {
test()
}
private fun module(
name: String,
modulePath: List<File> = emptyList(),
@@ -120,8 +116,7 @@ abstract class AbstractJavaModulesIntegrationTest(
module("moduleB", listOf(a))
}
// TODO (KT-60797): missing JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE.
fun testSimpleUseNonExportedPackage() = muteForK2 {
fun testSimpleUseNonExportedPackage() {
val a = module("moduleA")
module("moduleB", listOf(a))
}
@@ -133,8 +128,7 @@ abstract class AbstractJavaModulesIntegrationTest(
module("moduleD", listOf(a, b, c))
}
// TODO (KT-60797): missing JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE.
fun testUnnamedDependsOnNamed() = muteForK2 {
fun testUnnamedDependsOnNamed() {
val a = module("moduleA")
module("moduleB", listOf(a), listOf("moduleA"))
@@ -174,8 +168,7 @@ abstract class AbstractJavaModulesIntegrationTest(
}
}
// TODO (KT-60797): missing JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE.
fun testAutomaticModuleInternalJdkPackageUsage() = muteForK2 {
fun testAutomaticModuleInternalJdkPackageUsage() {
module("jvmStatUsage")
}
@@ -217,8 +210,7 @@ abstract class AbstractJavaModulesIntegrationTest(
module("moduleD", listOf(c, b, a))
}
// TODO (KT-60797): missing JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE.
fun testSpecifyPathToModuleInfoInArguments() = muteForK2 {
fun testSpecifyPathToModuleInfoInArguments() {
val a = module("moduleA")
val kotlinOptions = mutableListOf(
@@ -349,15 +341,13 @@ abstract class AbstractJavaModulesIntegrationTest(
})
}
// TODO (KT-60797): missing JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE.
fun testNoDependencyOnNamed() = muteForK2 {
fun testNoDependencyOnNamed() {
// This is a test on the JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE diagnostic.
val lib = module("lib")
module("main", listOf(lib), listOf("lib"))
}
// TODO (KT-60797): missing JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE.
fun testNoDependencyOnUnnamed() = muteForK2 {
fun testNoDependencyOnUnnamed() {
// This is a test on the JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE diagnostic.
// Most of the other tests in this class are compiling modules to jars, however here we need to compile the module to a directory.
// The reason is twofold: