diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/IdeJavaModuleResolver.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/IdeJavaModuleResolver.kt
index 18e395e2899..af5b8c58008 100644
--- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/IdeJavaModuleResolver.kt
+++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/IdeJavaModuleResolver.kt
@@ -46,26 +46,23 @@ class IdeJavaModuleResolver(private val project: Project) : JavaModuleResolver {
return JavaModuleResolver.AccessError.ModuleDoesNotReadModule(theirModule.name)
}
- val fqName = referencedPackage?.asString() ?: return null
- if (!exports(theirModule, fqName, ourModule)) {
- return JavaModuleResolver.AccessError.ModuleDoesNotExportPackage(theirModule.name)
+ // In the IDE, we allow unnamed module to access unexported package of the named module. The reason is that the compiler
+ // will use classpath, not the module path, when compilation of this module is launched from the IDE (because the module has
+ // no module-info). All of its dependencies will also land on the classpath, and everything is visible in the classpath,
+ // even non-exported packages of artifacts which would otherwise be loaded as named modules, if they were on the module path.
+ // So, no error will be reported from the compiler. Moreover, a run configuration of something from this unnamed module will also
+ // use classpath, not the module path, and in the same way everything will work at runtime as well.
+ if (ourModule != null) {
+ val fqName = referencedPackage?.asString() ?: return null
+ if (!exports(theirModule, fqName, ourModule)) {
+ return JavaModuleResolver.AccessError.ModuleDoesNotExportPackage(theirModule.name)
+ }
}
return null
}
// Returns whether or not [source] exports [packageName] to [target]
- private fun exports(source: PsiJavaModule, packageName: String, target: PsiJavaModule?): Boolean {
- if (source is LightJavaModule) {
- return true
- }
-
- // TODO: simply call JavaModuleGraphUtil.exports as soon as its 'target' parameter is nullable
- if (target != null) {
- return JavaModuleGraphUtil.exports(source, packageName, target)
- }
- return source.exports.any { statement ->
- statement.moduleNames.isEmpty() && statement.packageName == packageName
- }
- }
+ private fun exports(source: PsiJavaModule, packageName: String, target: PsiJavaModule): Boolean =
+ source is LightJavaModule || JavaModuleGraphUtil.exports(source, packageName, target)
}
diff --git a/idea/testData/multiModuleHighlighting/java9/exportsTo/unnamed/unnamedUsage.kt b/idea/testData/multiModuleHighlighting/java9/exportsTo/unnamed/unnamedUsage.kt
index a6b343c3ada..f542118d560 100644
--- a/idea/testData/multiModuleHighlighting/java9/exportsTo/unnamed/unnamedUsage.kt
+++ b/idea/testData/multiModuleHighlighting/java9/exportsTo/unnamed/unnamedUsage.kt
@@ -1,6 +1,6 @@
-import dependency.Foo
+import dependency.Foo
fun unnamedUsage(): String {
- val foo: Foo = Foo()
- return foo.toString()
+ val foo: Foo = Foo()
+ return foo.toString()
}
diff --git a/idea/testData/multiModuleHighlighting/java9/unnamedDependsOnNamed/main/usage.kt b/idea/testData/multiModuleHighlighting/java9/unnamedDependsOnNamed/main/usage.kt
index d90a85f266f..b16b4ac9272 100644
--- a/idea/testData/multiModuleHighlighting/java9/unnamedDependsOnNamed/main/usage.kt
+++ b/idea/testData/multiModuleHighlighting/java9/unnamedDependsOnNamed/main/usage.kt
@@ -2,15 +2,15 @@ import dependency.*
import dependency.J
import dependency.K
import dependency.impl.*
-import dependency.impl.JImpl
-import dependency.impl.KImpl
+import dependency.impl.JImpl
+import dependency.impl.KImpl
fun usage(): String {
val j: J = J.getInstance()
val k: K = K.getInstance()
- val jImpl: JImpl = J.getInstance()
- val kImpl: KImpl = K.getInstance()
+ val jImpl: JImpl = J.getInstance()
+ val kImpl: KImpl = K.getInstance()
return "$j$k$jImpl$kImpl"
}