code-moniker-workspace 0.4.0

Workspace model, ports, snapshots, linkage, and change analysis for code-moniker.
Documentation
use code_moniker_core::core::moniker::Moniker;
use code_moniker_core::lang::Lang;
use code_moniker_core::lang::build_manifest::Manifest;
use rustc_hash::FxHashSet;

use crate::linkage::binding::ReferenceLinkageDecision;
use crate::linkage::catalog::LinkageQuery;
use crate::linkage::catalog::{CandidateCatalog, LinkageCandidate};
use crate::snapshot::{RecordTable, ReferenceRecord};
use crate::source::CodeIndexMaterial;

mod generic;
mod go;
mod java;
mod python;
mod rust;
mod ts;

pub(super) trait LanguageLinkageStrategy: Sync {
	fn matches(&self, query: &LinkageQuery<'_>, candidate: &LinkageCandidate<'_>) -> bool;
}

static GENERIC_STRATEGY: generic::GenericLanguageLinkageStrategy =
	generic::GenericLanguageLinkageStrategy;
static GO_STRATEGY: go::GoLanguageLinkageStrategy = go::GoLanguageLinkageStrategy;
static JAVA_STRATEGY: java::JavaLanguageLinkageStrategy = java::JavaLanguageLinkageStrategy;
static PYTHON_STRATEGY: python::PythonLanguageLinkageStrategy =
	python::PythonLanguageLinkageStrategy;
static RUST_STRATEGY: rust::RustLanguageLinkageStrategy = rust::RustLanguageLinkageStrategy;
static TS_STRATEGY: ts::TsLanguageLinkageStrategy = ts::TsLanguageLinkageStrategy;

pub(super) fn language_strategy(lang: Lang) -> &'static dyn LanguageLinkageStrategy {
	match lang {
		Lang::Java => &JAVA_STRATEGY,
		Lang::Python => &PYTHON_STRATEGY,
		Lang::Rs => &RUST_STRATEGY,
		Lang::Ts => &TS_STRATEGY,
		Lang::Go => &GO_STRATEGY,
		Lang::Cs | Lang::Sql => &GENERIC_STRATEGY,
	}
}

pub(super) fn matches_candidate(
	query: &LinkageQuery<'_>,
	candidate: &LinkageCandidate<'_>,
) -> bool {
	query
		.material
		.files
		.get(query.source_file)
		.is_some_and(|file| language_strategy(file.lang).matches(query, candidate))
}

pub(super) fn manifest_for_lang(lang: Lang) -> Option<Manifest> {
	match lang {
		Lang::Ts => Some(Manifest::PackageJson),
		Lang::Rs => Some(Manifest::Cargo),
		Lang::Java => Some(Manifest::PomXml),
		Lang::Python => Some(Manifest::Pyproject),
		Lang::Go => Some(Manifest::GoMod),
		Lang::Cs => Some(Manifest::Csproj),
		Lang::Sql => None,
	}
}

pub(super) fn builtin_external_root(lang: Lang, root: &str) -> bool {
	match lang {
		Lang::Rs => rust::builtin_external_root(root),
		Lang::Java => java::builtin_external_root(root),
		Lang::Ts => ts::builtin_external_root(root),
		Lang::Python => code_moniker_core::lang::python::builtin_external_root(root),
		Lang::Go => code_moniker_core::lang::go::builtin_external_root(root),
		_ => false,
	}
}

pub(super) fn package_prefix_for_target(lang: Lang, target: &Moniker) -> Option<String> {
	match lang {
		Lang::Java => java::package_prefix(target),
		Lang::Ts => ts::package_prefix(target),
		_ => None,
	}
}

pub(super) fn source_declares_external_package(
	lang: Lang,
	manifest: Manifest,
	deps: &FxHashSet<String>,
	package_prefix: &str,
	query_confidence: Option<&str>,
	workspace_declares_package: impl Fn(&str) -> bool,
) -> bool {
	match lang {
		Lang::Java => java::source_declares_external_package(
			manifest,
			deps,
			package_prefix,
			query_confidence,
			workspace_declares_package,
		),
		Lang::Ts => ts::source_declares_external_package(
			manifest,
			deps,
			package_prefix,
			query_confidence,
			workspace_declares_package,
		),
		_ => false,
	}
}

pub(super) fn proc_macro_annotation(query: &LinkageQuery<'_>) -> bool {
	rust::proc_macro_annotation(query)
}

pub(super) struct SemanticContext<'a> {
	pub(super) material: &'a CodeIndexMaterial,
	pub(super) candidates: &'a CandidateCatalog,
	pub(super) locations: &'a crate::linkage::catalog::ReferenceLocations,
	pub(super) source_groups: &'a crate::linkage::source_groups::SourceGroupPolicy,
}

pub(super) fn enhance_reference_semantics(
	context: &SemanticContext<'_>,
	extends_of: &rustc_hash::FxHashMap<
		code_moniker_core::core::moniker::Moniker,
		code_moniker_core::core::moniker::Moniker,
	>,
	decisions: &mut [ReferenceLinkageDecision],
	references: &RecordTable<ReferenceRecord>,
	changed_references: Option<&rustc_hash::FxHashSet<crate::snapshot::ReferenceId>>,
) {
	java::enhance_reference_semantics(
		context,
		extends_of,
		decisions,
		references,
		changed_references,
	);
}