Allow to access unexported package of named module in unnamed module in IDE
#KT-19492 Fixed
This commit is contained in:
@@ -46,26 +46,23 @@ class IdeJavaModuleResolver(private val project: Project) : JavaModuleResolver {
|
|||||||
return JavaModuleResolver.AccessError.ModuleDoesNotReadModule(theirModule.name)
|
return JavaModuleResolver.AccessError.ModuleDoesNotReadModule(theirModule.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
val fqName = referencedPackage?.asString() ?: return null
|
// In the IDE, we allow unnamed module to access unexported package of the named module. The reason is that the compiler
|
||||||
if (!exports(theirModule, fqName, ourModule)) {
|
// will use classpath, not the module path, when compilation of this module is launched from the IDE (because the module has
|
||||||
return JavaModuleResolver.AccessError.ModuleDoesNotExportPackage(theirModule.name)
|
// 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
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether or not [source] exports [packageName] to [target]
|
// Returns whether or not [source] exports [packageName] to [target]
|
||||||
private fun exports(source: PsiJavaModule, packageName: String, target: PsiJavaModule?): Boolean {
|
private fun exports(source: PsiJavaModule, packageName: String, target: PsiJavaModule): Boolean =
|
||||||
if (source is LightJavaModule) {
|
source is LightJavaModule || JavaModuleGraphUtil.exports(source, packageName, target)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
import dependency.<error>Foo</error>
|
import dependency.Foo
|
||||||
|
|
||||||
fun unnamedUsage(): String {
|
fun unnamedUsage(): String {
|
||||||
val foo: <error>Foo</error> = <error>Foo</error>()
|
val foo: Foo = Foo()
|
||||||
return foo.<error>toString</error>()
|
return foo.toString()
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -2,15 +2,15 @@ import dependency.*
|
|||||||
import dependency.J
|
import dependency.J
|
||||||
import dependency.K
|
import dependency.K
|
||||||
import dependency.impl.*
|
import dependency.impl.*
|
||||||
import dependency.impl.<error>JImpl</error>
|
import dependency.impl.JImpl
|
||||||
import dependency.impl.<error>KImpl</error>
|
import dependency.impl.KImpl
|
||||||
|
|
||||||
fun usage(): String {
|
fun usage(): String {
|
||||||
val j: J = J.getInstance()
|
val j: J = J.getInstance()
|
||||||
val k: K = K.getInstance()
|
val k: K = K.getInstance()
|
||||||
|
|
||||||
val jImpl: <error>JImpl</error> = J.getInstance()
|
val jImpl: JImpl = J.getInstance()
|
||||||
val kImpl: <error>KImpl</error> = K.getInstance()
|
val kImpl: KImpl = K.getInstance()
|
||||||
|
|
||||||
return "$j$k$jImpl$kImpl"
|
return "$j$k$jImpl$kImpl"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user