Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,75 +19,82 @@ private val logger = LoggerFactory.getLogger("WorkspaceExts")

internal fun Workspace.collectKtModules(
project: Project,
appEnv: CoreApplicationEnvironment
): List<KtModule> = buildList {
fun addModule(module: KtModule) = add(module)
appEnv: CoreApplicationEnvironment,
): List<KtModule> =
buildList {
fun addModule(module: KtModule) = add(module)

val moduleProjects = subProjects
.asSequence()
.filterIsInstance<ModuleProject>()
.filter { it.path != rootProject.path }

val jarToModMap = mutableMapOf<Path, KtLibraryModule>()

fun addLibrary(path: Path): KtLibraryModule {
val module = buildKtLibraryModule(project, appEnv) {
id = path.pathString
addContentRoot(path)
}
jarToModMap[path] = module
return module
}

val bootClassPaths = moduleProjects
.filterIsInstance<AndroidModule>()
.flatMap { project ->
project.bootClassPaths
val moduleProjects =
subProjects
.asSequence()
.filterIsInstance<ModuleProject>()
.filter { it.path != rootProject.path }

val jarToModMap = mutableMapOf<Path, KtLibraryModule>()

// One module per jar: every module shares android.jar, and each KtLibraryModule
// materializes the jar's full file list for its search scope (ADFA-6381).
fun addLibrary(path: Path): KtLibraryModule =
jarToModMap.getOrPut(path) {
buildKtLibraryModule(project, appEnv) {
id = path.pathString
addContentRoot(path)
}
}

// A List, not a Sequence: a Sequence would re-run addLibrary for every source module below.
val bootClassPaths =
moduleProjects
.filterIsInstance<AndroidModule>()
.flatMap { it.bootClassPaths.asSequence() }
.filter { it.exists() }
.map { it.toPath() }
.distinct()
.map(::addLibrary)
}
.toList()

val libraryDependencies = moduleProjects
.flatMap { it.getCompileClasspaths() }
.filter { it.exists() }
.map { it.toPath() }
.associateWith(::addLibrary)

val subprojectsAsModules = mutableMapOf<ModuleProject, KtSourceModule>()
val sourceRootToModuleMap = mutableMapOf<Path, KtSourceModule>()

fun getOrCreateModule(moduleProject: ModuleProject): KtSourceModule {
subprojectsAsModules[moduleProject]?.let { return it }

val module = buildKtSourceModule(project) {
this.module = moduleProject

bootClassPaths.forEach { addDependency(it) }

moduleProject.getCompileClasspaths(excludeSourceGeneratedClassPath = true)
.forEach { classpath ->
val libDep = libraryDependencies[classpath.toPath()]
if (libDep == null) {
logger.error(
"Skipping non-existent classpath classpath: {}",
classpath
)
return@forEach
val libraryDependencies =
moduleProjects
.flatMap { it.getCompileClasspaths() }
.filter { it.exists() }
.map { it.toPath() }
.associateWith(::addLibrary)

val subprojectsAsModules = mutableMapOf<ModuleProject, KtSourceModule>()
val sourceRootToModuleMap = mutableMapOf<Path, KtSourceModule>()

fun getOrCreateModule(moduleProject: ModuleProject): KtSourceModule {
subprojectsAsModules[moduleProject]?.let { return it }

val module =
buildKtSourceModule(project) {
this.module = moduleProject

bootClassPaths.forEach { addDependency(it) }

moduleProject
.getCompileClasspaths(excludeSourceGeneratedClassPath = true)
.forEach { classpath ->
val libDep = libraryDependencies[classpath.toPath()]
if (libDep == null) {
logger.error(
"Skipping non-existent classpath classpath: {}",
classpath,
)
return@forEach
}
addDependency(libDep)
Comment thread
hal-eisen-adfa marked this conversation as resolved.
}

moduleProject.getCompileModuleProjects().forEach { dep ->
addDependency(getOrCreateModule(dep))
}
addDependency(libDep)
}

moduleProject.getCompileModuleProjects().forEach { dep ->
addDependency(getOrCreateModule(dep))
}
subprojectsAsModules[moduleProject] = module
module.contentRoots.forEach { root -> sourceRootToModuleMap[root] = module }
return module
}

subprojectsAsModules[moduleProject] = module
module.contentRoots.forEach { root -> sourceRootToModuleMap[root] = module }
return module
moduleProjects.forEach { addModule(getOrCreateModule(it)) }
}

moduleProjects.forEach { addModule(getOrCreateModule(it)) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,20 @@ internal class KtLibraryModule(
override val isSdk: Boolean = false,
private val jvmTarget: JvmTarget = DEFAULT_JVM_TARGET,
override val librarySources: KaLibrarySourceModule? = null,
) : KaLibraryModule,
AbstractKtModule(
) : AbstractKtModule(
project,
dependencies
) {

dependencies,
),
KaLibraryModule {
class Builder(
private val project: Project,
private val applicationEnvironment: CoreApplicationEnvironment,
) {
lateinit var id: String
private val contentRoots = mutableSetOf<Path>()
private val dependencies = mutableListOf<KtModule>()

// A set, like KtSourceModule.Builder: no module is a dependency twice.
private val dependencies = linkedSetOf<KtModule>()
var isSdk: Boolean = false
var jvmTarget: JvmTarget = DEFAULT_JVM_TARGET
var librarySources: KaLibrarySourceModule? = null
Expand All @@ -61,31 +62,37 @@ internal class KtLibraryModule(
dependencies.add(dep)
}

fun build(): KtLibraryModule = KtLibraryModule(
project = project,
id = id,
contentRoots = contentRoots.toSet(),
dependencies = dependencies.toList(),
applicationEnvironment = applicationEnvironment,
isSdk = isSdk,
jvmTarget = jvmTarget,
librarySources = librarySources,
)
fun build(): KtLibraryModule =
KtLibraryModule(
project = project,
id = id,
contentRoots = contentRoots.toSet(),
dependencies = dependencies.toList(),
applicationEnvironment = applicationEnvironment,
isSdk = isSdk,
jvmTarget = jvmTarget,
librarySources = librarySources,
)
}

@OptIn(KaImplementationDetail::class)
override fun computeFiles(extended: Boolean): Sequence<VirtualFile> {
val roots = if (isSdk) project.read {
LibraryUtils.findClassesFromJdkHome(
contentRoots.first(),
isJre = false
)
}
else contentRoots
val roots =
if (isSdk) {
project.read {
LibraryUtils.findClassesFromJdkHome(
contentRoots.first(),
isJre = false,
)
}
} else {
contentRoots
}

val notExtendedFiles = roots
.asSequence()
.mapNotNull { getVirtualFileForLibraryRoot(it, applicationEnvironment, project) }
val notExtendedFiles =
roots
.asSequence()
.mapNotNull { getVirtualFileForLibraryRoot(it, applicationEnvironment, project) }

if (!extended) return notExtendedFiles

Expand All @@ -97,17 +104,11 @@ internal class KtLibraryModule(
override val baseContentScope: GlobalSearchScope by lazy {
val virtualFileUrls = computeFiles(extended = true).map { it.url }.toSet()
object : GlobalSearchScope(project) {
override fun contains(vf: VirtualFile): Boolean {
return vf.url in virtualFileUrls
}
override fun contains(vf: VirtualFile): Boolean = vf.url in virtualFileUrls

override fun isSearchInModuleContent(module: Module): Boolean {
return false
}
override fun isSearchInModuleContent(module: Module): Boolean = false

override fun isSearchInLibraries(): Boolean {
return true
}
override fun isSearchInLibraries(): Boolean = true
}
}

Expand Down Expand Up @@ -136,6 +137,7 @@ internal fun buildKtLibraryModule(
): KtLibraryModule = KtLibraryModule.Builder(project, applicationEnvironment).apply(init).build()

private const val JAR_SEPARATOR = "!/"

private fun getVirtualFileForLibraryRoot(
root: Path,
environment: CoreApplicationEnvironment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,19 @@ internal class KtSourceModule(
project: Project,
val module: ModuleProject,
directRegularDependencies: List<KtModule>,
) : KaSourceModule, AbstractSourceModule(project, directRegularDependencies) {

) : AbstractSourceModule(project, directRegularDependencies),
KaSourceModule {
companion object {
private val logger = LoggerFactory.getLogger(KtSourceModule::class.java)
}

class Builder(private val project: Project) {
class Builder(
private val project: Project,
) {
lateinit var module: ModuleProject
private val dependencies = mutableListOf<KtModule>()

// A set: a jar on both the boot and compile classpath is one shared module (ADFA-6381).
private val dependencies = linkedSetOf<KtModule>()

fun addDependency(dep: KtModule) {
dependencies.add(dep)
Expand All @@ -42,29 +46,38 @@ internal class KtSourceModule(
get() = module.path

override val contentRoots by lazy {
module.getSourceDirectories()
module
.getSourceDirectories()
.asSequence()
.map { it.toPath() }
.toSet()
}

private val versions by lazy {
val kotlinCompilerSettings = when {
module.hasJavaProject() -> module.javaProject
.kotlinCompilerSettings

module.hasAndroidProject() -> module.androidProject
.kotlinCompilerSettings

else -> null
}
val kotlinCompilerSettings =
when {
module.hasJavaProject() -> {
module.javaProject
.kotlinCompilerSettings
}

module.hasAndroidProject() -> {
module.androidProject
.kotlinCompilerSettings
}

else -> {
null
}
}

if (kotlinCompilerSettings == null) {
return@lazy DEFAULT_LANGUAGE_VERSION to DEFAULT_JVM_TARGET
}

val apiVersion = LanguageVersion.fromVersionString(kotlinCompilerSettings.apiVersion)
?: LanguageVersion.fromFullVersionString(kotlinCompilerSettings.apiVersion)
val apiVersion =
LanguageVersion.fromVersionString(kotlinCompilerSettings.apiVersion)
?: LanguageVersion.fromFullVersionString(kotlinCompilerSettings.apiVersion)

val jvmTarget = JvmTarget.fromString(kotlinCompilerSettings.jvmTarget)

Expand All @@ -79,18 +92,17 @@ internal class KtSourceModule(
get() = super<AbstractSourceModule>.moduleDescription

override val languageVersionSettings: LanguageVersionSettings
get() = LanguageVersionSettingsImpl(
languageVersion = versions.first,
apiVersion = ApiVersion.createByLanguageVersion(versions.first),
)
get() =
LanguageVersionSettingsImpl(
languageVersion = versions.first,
apiVersion = ApiVersion.createByLanguageVersion(versions.first),
)

override val targetPlatform: TargetPlatform
get() = JvmPlatforms.jvmPlatformByTargetVersion(versions.second)


}

internal fun buildKtSourceModule(
project: Project,
init: KtSourceModule.Builder.() -> Unit,
): KtSourceModule = KtSourceModule.Builder(project).apply(init).build()
): KtSourceModule = KtSourceModule.Builder(project).apply(init).build()
Loading
Loading