From 8d13b46ce49a9104d4898f0e7fe7ff8269a7b1c0 Mon Sep 17 00:00:00 2001 From: Tomasz Pasternak Date: Wed, 17 Apr 2024 14:53:43 +0000 Subject: [PATCH] [feature] Add a flag that makes the algorithm more likely to interpret target as a library than a module Merge-request: BAZEL-MR-1039 Merged-by: Xuan Son Trinh --- .../bazel/projectview/model/ProjectView.kt | 19 ++++++++++++++++++- .../sections/ProjectViewSingletonSection.kt | 7 +++++++ .../parser/DefaultProjectViewParser.kt | 3 ++- .../ProjectViewSingletonSectionParser.kt | 10 ++++++++++ .../ExperimentalUseLibOverModSpec.kt | 14 ++++++++++++++ .../workspacecontext/WorkspaceContext.kt | 3 +++ .../install/ProjectViewCLiOptionsProvider.kt | 1 + .../bazel/server/sync/BazelProjectMapper.kt | 13 ++++++------- 8 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 executioncontext/workspacecontext/src/main/kotlin/org/jetbrains/bsp/bazel/workspacecontext/ExperimentalUseLibOverModSpec.kt diff --git a/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/model/ProjectView.kt b/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/model/ProjectView.kt index c99437f70..83dc3614f 100644 --- a/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/model/ProjectView.kt +++ b/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/model/ProjectView.kt @@ -1,6 +1,7 @@ package org.jetbrains.bsp.bazel.projectview.model import org.apache.logging.log4j.LogManager +import org.jetbrains.bsp.bazel.projectview.model.sections.ExperimentalUseLibOverModSection import org.jetbrains.bsp.bazel.projectview.model.sections.ProjectViewBazelBinarySection import org.jetbrains.bsp.bazel.projectview.model.sections.ProjectViewBuildFlagsSection import org.jetbrains.bsp.bazel.projectview.model.sections.ProjectViewBuildManualTargetsSection @@ -38,6 +39,8 @@ data class ProjectView( val enabledRules: ProjectViewEnabledRulesSection?, /** local java home path to override to use with IDE, e.g. IntelliJ IDEA */ val ideJavaHomeOverride: ProjectViewIdeJavaHomeOverrideSection?, + /** use a new predicate that is more likely to interpret targets as libraries than as modules */ + val useLibOverModSection: ExperimentalUseLibOverModSection? = null, ) { data class Builder( @@ -51,6 +54,8 @@ data class ProjectView( private val importDepth: ProjectViewImportDepthSection? = null, private val enabledRules: ProjectViewEnabledRulesSection? = null, private val ideJavaHomeOverride: ProjectViewIdeJavaHomeOverrideSection? = null, + private val useLibOverModSection: ExperimentalUseLibOverModSection? = null, + ) { fun build(): ProjectView { @@ -69,6 +74,8 @@ data class ProjectView( val importDepth = combineImportDepthSection(importedProjectViews) val enabledRules = combineEnabledRulesSection(importedProjectViews) val ideJavaHomeOverride = combineIdeJavaHomeOverrideSection(importedProjectViews) + val useLibOverModSection = combineUseLibOverModSection(importedProjectViews) + log.debug( "Building project view with combined" + " targets: {}," @@ -79,7 +86,8 @@ data class ProjectView( + " deriveTargetsFlag: {}." + " import depth: {}," + " enabled rules: {}," - + " ideJavaHomeOverride: {},", + + " ideJavaHomeOverride: {}," + + " useLibOverModSection: {},", targets, bazelBinary, buildFlags, @@ -89,6 +97,7 @@ data class ProjectView( importDepth, enabledRules, ideJavaHomeOverride, + useLibOverModSection ) return ProjectView( targets, @@ -100,6 +109,14 @@ data class ProjectView( importDepth, enabledRules, ideJavaHomeOverride, + useLibOverModSection, + ) + } + + private fun combineUseLibOverModSection(importedProjectViews: List): ExperimentalUseLibOverModSection? { + return useLibOverModSection ?: getLastImportedSingletonValue( + importedProjectViews, + ProjectView::useLibOverModSection ) } diff --git a/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/model/sections/ProjectViewSingletonSection.kt b/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/model/sections/ProjectViewSingletonSection.kt index 750854548..9b1aae2e3 100644 --- a/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/model/sections/ProjectViewSingletonSection.kt +++ b/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/model/sections/ProjectViewSingletonSection.kt @@ -40,3 +40,10 @@ data class ProjectViewImportDepthSection(override val value: Int) : const val SECTION_NAME = "import_depth" } } + +data class ExperimentalUseLibOverModSection(override val value: Boolean) : + ProjectViewSingletonSection(SECTION_NAME) { + companion object { + const val SECTION_NAME = "experimental_use_lib_over_mod" + } +} diff --git a/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/parser/DefaultProjectViewParser.kt b/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/parser/DefaultProjectViewParser.kt index 450c39ece..e170abb02 100644 --- a/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/parser/DefaultProjectViewParser.kt +++ b/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/parser/DefaultProjectViewParser.kt @@ -3,7 +3,7 @@ package org.jetbrains.bsp.bazel.projectview.parser import org.apache.logging.log4j.LogManager import org.jetbrains.bsp.bazel.commons.escapeNewLines import org.jetbrains.bsp.bazel.projectview.model.ProjectView -import org.jetbrains.bsp.bazel.projectview.model.sections.ProjectViewIdeJavaHomeOverrideSection +import org.jetbrains.bsp.bazel.projectview.parser.sections.ExperimentalUseLibOverModSectionParser; import org.jetbrains.bsp.bazel.projectview.parser.sections.ProjectViewBazelBinarySectionParser import org.jetbrains.bsp.bazel.projectview.parser.sections.ProjectViewBuildFlagsSectionParser import org.jetbrains.bsp.bazel.projectview.parser.sections.ProjectViewBuildManualTargetsSectionParser @@ -43,6 +43,7 @@ open class DefaultProjectViewParser : ProjectViewParser { importDepth = ProjectViewImportDepthSectionParser.parse(rawSections), enabledRules = ProjectViewEnabledRulesSectionParser.parse(rawSections), ideJavaHomeOverride = ProjectViewIdeJavaHomeOverrideSectionParser.parse(rawSections), + useLibOverModSection = ExperimentalUseLibOverModSectionParser.parse(rawSections) ).build() } diff --git a/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/parser/sections/ProjectViewSingletonSectionParser.kt b/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/parser/sections/ProjectViewSingletonSectionParser.kt index e72ea6369..06759a982 100644 --- a/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/parser/sections/ProjectViewSingletonSectionParser.kt +++ b/executioncontext/projectview/src/main/kotlin/org/jetbrains/bsp/bazel/projectview/parser/sections/ProjectViewSingletonSectionParser.kt @@ -1,6 +1,7 @@ package org.jetbrains.bsp.bazel.projectview.parser.sections import org.apache.logging.log4j.LogManager +import org.jetbrains.bsp.bazel.projectview.model.sections.ExperimentalUseLibOverModSection import org.jetbrains.bsp.bazel.projectview.model.sections.ProjectViewBazelBinarySection import org.jetbrains.bsp.bazel.projectview.model.sections.ProjectViewBuildManualTargetsSection import org.jetbrains.bsp.bazel.projectview.model.sections.ProjectViewDeriveTargetsFromDirectoriesSection @@ -87,3 +88,12 @@ object ProjectViewIdeJavaHomeOverrideSectionParser : override fun createInstance(value: Path): ProjectViewIdeJavaHomeOverrideSection = ProjectViewIdeJavaHomeOverrideSection(value) } + +object ExperimentalUseLibOverModSectionParser : + ProjectViewSingletonSectionParser(ExperimentalUseLibOverModSection.SECTION_NAME) { + + override fun mapRawValue(rawValue: String): Boolean = rawValue.toBoolean() + + override fun createInstance(value: Boolean): ExperimentalUseLibOverModSection = + ExperimentalUseLibOverModSection(value) +} \ No newline at end of file diff --git a/executioncontext/workspacecontext/src/main/kotlin/org/jetbrains/bsp/bazel/workspacecontext/ExperimentalUseLibOverModSpec.kt b/executioncontext/workspacecontext/src/main/kotlin/org/jetbrains/bsp/bazel/workspacecontext/ExperimentalUseLibOverModSpec.kt new file mode 100644 index 000000000..e6f5d2685 --- /dev/null +++ b/executioncontext/workspacecontext/src/main/kotlin/org/jetbrains/bsp/bazel/workspacecontext/ExperimentalUseLibOverModSpec.kt @@ -0,0 +1,14 @@ +package org.jetbrains.bsp.bazel.workspacecontext + +import org.jetbrains.bsp.bazel.executioncontext.api.ExecutionContextEntityExtractor +import org.jetbrains.bsp.bazel.executioncontext.api.ExecutionContextSingletonEntity +import org.jetbrains.bsp.bazel.projectview.model.ProjectView + +data class ExperimentalUseLibOverModSpec( + override val value: Boolean, +) : ExecutionContextSingletonEntity() + +internal object ExperimentalUseLibOverModSpecExtractor : ExecutionContextEntityExtractor { + override fun fromProjectView(projectView: ProjectView): ExperimentalUseLibOverModSpec = + ExperimentalUseLibOverModSpec(projectView.useLibOverModSection?.value ?: false) +} \ No newline at end of file diff --git a/executioncontext/workspacecontext/src/main/kotlin/org/jetbrains/bsp/bazel/workspacecontext/WorkspaceContext.kt b/executioncontext/workspacecontext/src/main/kotlin/org/jetbrains/bsp/bazel/workspacecontext/WorkspaceContext.kt index 43e5d33fe..2a8a28819 100644 --- a/executioncontext/workspacecontext/src/main/kotlin/org/jetbrains/bsp/bazel/workspacecontext/WorkspaceContext.kt +++ b/executioncontext/workspacecontext/src/main/kotlin/org/jetbrains/bsp/bazel/workspacecontext/WorkspaceContext.kt @@ -76,6 +76,8 @@ data class WorkspaceContext( * Obtained from `ProjectView` simply by mapping `ide_java_home_override` section. */ val ideJavaHomeOverrideSpec: IdeJavaHomeOverrideSpec, + + val experimentalUseLibOverModSection: ExperimentalUseLibOverModSpec ) : ExecutionContext() class WorkspaceContextConstructor(workspaceRoot: Path) : ExecutionContextConstructor { @@ -98,6 +100,7 @@ class WorkspaceContextConstructor(workspaceRoot: Path) : ExecutionContextConstru importDepth = ImportDepthSpecExtractor.fromProjectView(projectView), enabledRules = EnabledRulesSpecExtractor.fromProjectView(projectView), ideJavaHomeOverrideSpec = IdeJavaHomeOverrideSpecExtractor.fromProjectView(projectView), + experimentalUseLibOverModSection = ExperimentalUseLibOverModSpecExtractor.fromProjectView(projectView), ) } } diff --git a/install/src/main/kotlin/org/jetbrains/bsp/bazel/install/ProjectViewCLiOptionsProvider.kt b/install/src/main/kotlin/org/jetbrains/bsp/bazel/install/ProjectViewCLiOptionsProvider.kt index c70558cd4..dba33d015 100644 --- a/install/src/main/kotlin/org/jetbrains/bsp/bazel/install/ProjectViewCLiOptionsProvider.kt +++ b/install/src/main/kotlin/org/jetbrains/bsp/bazel/install/ProjectViewCLiOptionsProvider.kt @@ -36,6 +36,7 @@ object ProjectViewCLiOptionsProvider { buildManualTargets = toBuildManualTargetsSection(projectViewCliOptions), enabledRules = toEnabledRulesSection(projectViewCliOptions), ideJavaHomeOverride = toIdeJavaHomeOverrideSection(projectViewCliOptions), + useLibOverModSection = null, // Experimental flag, no need to be configurable via CLI ) private fun toBazelBinarySection(projectViewCliOptions: ProjectViewCliOptions?): ProjectViewBazelBinarySection? = diff --git a/server/src/main/kotlin/org/jetbrains/bsp/bazel/server/sync/BazelProjectMapper.kt b/server/src/main/kotlin/org/jetbrains/bsp/bazel/server/sync/BazelProjectMapper.kt index 3d2aa143e..911525694 100644 --- a/server/src/main/kotlin/org/jetbrains/bsp/bazel/server/sync/BazelProjectMapper.kt +++ b/server/src/main/kotlin/org/jetbrains/bsp/bazel/server/sync/BazelProjectMapper.kt @@ -8,7 +8,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking import org.jetbrains.bsp.bazel.bazelrunner.BazelInfo -import org.jetbrains.bsp.bazel.info.BspTargetInfo import org.jetbrains.bsp.bazel.info.BspTargetInfo.FileLocation import org.jetbrains.bsp.bazel.info.BspTargetInfo.TargetInfo import org.jetbrains.bsp.bazel.logger.BspClientLogger @@ -108,7 +107,7 @@ class BazelProjectMapper( (removeDotBazelBspTarget(allTargetNames) - targetsToImport.map(TargetInfo::getId).toSet()).map { Label(it) } } val rustExternalTargetsToImport = measure("Select external Rust targets") { - selectRustExternalTargetsToImport(rootTargets, dependencyGraph) + selectRustExternalTargetsToImport(rootTargets, dependencyGraph, workspaceContext) } val rustExternalModules = measure("Create Rust external modules") { createRustExternalModules(rustExternalTargetsToImport, dependencyGraph, librariesFromDeps) @@ -386,15 +385,15 @@ class BazelProjectMapper( .toSet() private fun selectRustExternalTargetsToImport( - rootTargets: Set, graph: DependencyGraph + rootTargets: Set, graph: DependencyGraph, workspaceContext: WorkspaceContext ): Sequence = - graph.allTargetsAtDepth(-1, rootTargets).asSequence().filter { !isWorkspaceTarget(it) && isRustTarget(it) } + graph.allTargetsAtDepth(-1, rootTargets).asSequence().filter { !isWorkspaceTarget(it, workspaceContext) && isRustTarget(it) } private fun selectTargetsToImport( workspaceContext: WorkspaceContext, rootTargets: Set, graph: DependencyGraph ): Sequence = graph.allTargetsAtDepth( workspaceContext.importDepth.value, rootTargets - ).asSequence().filter(::isWorkspaceTarget) + ).asSequence().filter { isWorkspaceTarget(it, workspaceContext) } private fun hasKnownSources(targetInfo: TargetInfo) = targetInfo.sourcesList.any { @@ -406,9 +405,9 @@ class BazelProjectMapper( it.relativePath.endsWith(".rs") } - private fun isWorkspaceTarget(target: TargetInfo): Boolean = + private fun isWorkspaceTarget(target: TargetInfo, workspaceContext: WorkspaceContext): Boolean = bazelInfo.release.isRelativeWorkspacePath(target.id) && - (hasKnownSources(target) || + (hasKnownSources(target) || !workspaceContext.experimentalUseLibOverModSection.value && target.kind in setOf( "java_library", "java_binary",