Fix internal-visibility mangling in IDE

Collect module name properly from facets settings, using CLI arguments
which define module name ('-module-name' on JVM and Common,
'-output-file' on JS).

^KT-23668 Fixed
This commit is contained in:
Dmitry Savvinov
2018-06-30 16:08:59 +03:00
parent 04f12846f1
commit 2783e9939b
18 changed files with 473 additions and 22 deletions
@@ -281,7 +281,8 @@ internal object IDELightClassContexts {
private fun setupAdHocResolve(project: Project, realWorldModule: ModuleDescriptor, files: List<KtFile>): ResolveSession {
val trace = BindingTraceContext()
val sm = LockBasedStorageManager.NO_LOCKS
val moduleDescriptor = ModuleDescriptorImpl(realWorldModule.name, sm, realWorldModule.builtIns)
val moduleDescriptor =
ModuleDescriptorImpl(realWorldModule.name, sm, realWorldModule.builtIns, stableName = realWorldModule.stableName)
moduleDescriptor.setDependencies(moduleDescriptor, moduleDescriptor.builtIns.builtInsModule)
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware
import org.jetbrains.kotlin.idea.framework.getLibraryPlatform
import org.jetbrains.kotlin.idea.project.KotlinModuleModificationTracker
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.idea.project.getStableName
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
import org.jetbrains.kotlin.idea.util.isInSourceContentWithoutInjected
import org.jetbrains.kotlin.idea.util.rootManager
@@ -158,6 +159,8 @@ data class ModuleProductionSourceInfo internal constructor(
override val name = Name.special("<production sources for module ${module.name}>")
override val stableName: Name = module.getStableName()
override fun contentScope(): GlobalSearchScope = ModuleProductionSourceScope(module)
override fun <T> createCachedValueProvider(f: () -> CachedValueProvider.Result<T>) = CachedValueProvider { f() }
@@ -170,6 +173,8 @@ data class ModuleTestSourceInfo internal constructor(override val module: Module
override val name = Name.special("<test sources for module ${module.name}>")
override val stableName: Name = module.getStableName()
override val displayedName get() = module.name + " (test)"
override fun contentScope(): GlobalSearchScope = ModuleTestSourceScope(module)
@@ -24,6 +24,7 @@ import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.roots.ProjectRootModificationTracker
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
@@ -36,11 +37,13 @@ import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgume
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings
import org.jetbrains.kotlin.idea.facet.getLibraryLanguageLevel
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.utils.Jsr305State
import java.io.File
val KtElement.platform: TargetPlatform
get() = TargetPlatformDetector.getPlatform(containingKtFile)
@@ -78,6 +81,32 @@ fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion {
return languageLevel
}
/**
* Returns stable binary name of module from the *Kotlin* point of view.
* Having correct module name is critical for compiler, e.g. for 'internal'-visibility
* mangling (see KT-23668).
*
* Note that build systems and IDEA have their own module systems and, potentially, their
* names can be different from Kotlin module name (though this is the rare case).
*/
fun Module.getStableName(): Name {
// Here we check ideal situation: we have a facet, and it has 'moduleName' argument.
// This should be the case for the most environments
val arguments = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this).mergedCompilerArguments
val explicitNameFromArguments = when (arguments) {
is K2JVMCompilerArguments -> arguments.moduleName
is K2JSCompilerArguments -> arguments.outputFile?.let { FileUtil.getNameWithoutExtension(File(it)) }
is K2MetadataCompilerArguments -> arguments.moduleName
else -> null // Actually, only 'null' possible here
}
// Here we handle pessimistic case: no facet is found or it declares no 'moduleName'
// We heuristically assume that name of Module in IDEA is the same as Kotlin module (which may be not the case)
val stableNameApproximation = explicitNameFromArguments ?: name
return Name.special("<$stableNameApproximation>")
}
@JvmOverloads
fun Project.getLanguageVersionSettings(
contextModule: Module? = null,