mirror of
https://github.com/martinvonz/jj.git
synced 2024-12-25 05:29:39 +00:00
revset: convert commit and change prefix resolvers into partial symbol resolvers
This commit is contained in:
parent
7bdf2b3945
commit
bad9e9e3d7
2 changed files with 71 additions and 63 deletions
|
@ -159,13 +159,7 @@ pub fn default_symbol_resolver<'a>(
|
|||
repo: &'a dyn Repo,
|
||||
id_prefix_context: &'a IdPrefixContext,
|
||||
) -> DefaultSymbolResolver<'a> {
|
||||
let commit_id_resolver: revset::PrefixResolver<CommitId> =
|
||||
Box::new(|repo, prefix| id_prefix_context.resolve_commit_prefix(repo, prefix));
|
||||
let change_id_resolver: revset::PrefixResolver<Vec<CommitId>> =
|
||||
Box::new(|repo, prefix| id_prefix_context.resolve_change_prefix(repo, prefix));
|
||||
DefaultSymbolResolver::new(repo)
|
||||
.with_commit_id_resolver(commit_id_resolver)
|
||||
.with_change_id_resolver(change_id_resolver)
|
||||
DefaultSymbolResolver::new(repo).with_id_prefix_context(id_prefix_context)
|
||||
}
|
||||
|
||||
/// Parses user-configured expression defining the immutable set.
|
||||
|
|
|
@ -37,6 +37,7 @@ use crate::dsl_util::{collect_similar, StringLiteralParser};
|
|||
use crate::fileset::{FilePattern, FilesetExpression, FilesetParseContext};
|
||||
use crate::git;
|
||||
use crate::hex_util::to_forward_hex;
|
||||
use crate::id_prefix::IdPrefixContext;
|
||||
use crate::object_id::{HexPrefix, PrefixResolution};
|
||||
use crate::op_store::WorkspaceId;
|
||||
use crate::repo::Repo;
|
||||
|
@ -2148,45 +2149,93 @@ impl PartialSymbolResolver for GitRefResolver {
|
|||
const DEFAULT_RESOLVERS: &[&'static dyn PartialSymbolResolver] =
|
||||
&[&TagResolver, &BranchResolver, &GitRefResolver];
|
||||
|
||||
pub type PrefixResolver<'a, T> = Box<dyn Fn(&dyn Repo, &HexPrefix) -> PrefixResolution<T> + 'a>;
|
||||
#[derive(Default)]
|
||||
struct CommitPrefixResolver<'a> {
|
||||
context: Option<&'a IdPrefixContext>,
|
||||
}
|
||||
|
||||
impl PartialSymbolResolver for CommitPrefixResolver<'_> {
|
||||
fn resolve_symbol(
|
||||
&self,
|
||||
repo: &dyn Repo,
|
||||
symbol: &str,
|
||||
) -> Result<Option<Vec<CommitId>>, RevsetResolutionError> {
|
||||
if let Some(prefix) = HexPrefix::new(symbol) {
|
||||
let resolution = self
|
||||
.context
|
||||
.as_ref()
|
||||
.map(|ctx| ctx.resolve_commit_prefix(repo, &prefix))
|
||||
.unwrap_or_else(|| repo.index().resolve_commit_id_prefix(&prefix));
|
||||
match resolution {
|
||||
PrefixResolution::AmbiguousMatch => Err(
|
||||
RevsetResolutionError::AmbiguousCommitIdPrefix(symbol.to_owned()),
|
||||
),
|
||||
PrefixResolution::SingleMatch(id) => Ok(Some(vec![id])),
|
||||
PrefixResolution::NoMatch => Ok(None),
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ChangePrefixResolver<'a> {
|
||||
context: Option<&'a IdPrefixContext>,
|
||||
}
|
||||
|
||||
impl PartialSymbolResolver for ChangePrefixResolver<'_> {
|
||||
fn resolve_symbol(
|
||||
&self,
|
||||
repo: &dyn Repo,
|
||||
symbol: &str,
|
||||
) -> Result<Option<Vec<CommitId>>, RevsetResolutionError> {
|
||||
if let Some(prefix) = to_forward_hex(symbol).as_deref().and_then(HexPrefix::new) {
|
||||
let resolution = self
|
||||
.context
|
||||
.as_ref()
|
||||
.map(|ctx| ctx.resolve_change_prefix(repo, &prefix))
|
||||
.unwrap_or_else(|| repo.resolve_change_id_prefix(&prefix));
|
||||
match resolution {
|
||||
PrefixResolution::AmbiguousMatch => Err(
|
||||
RevsetResolutionError::AmbiguousChangeIdPrefix(symbol.to_owned()),
|
||||
),
|
||||
PrefixResolution::SingleMatch(ids) => Ok(Some(ids)),
|
||||
PrefixResolution::NoMatch => Ok(None),
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves branches, remote branches, tags, git refs, and full and abbreviated
|
||||
/// commit and change ids.
|
||||
pub struct DefaultSymbolResolver<'a> {
|
||||
repo: &'a dyn Repo,
|
||||
commit_id_resolver: PrefixResolver<'a, CommitId>,
|
||||
change_id_resolver: PrefixResolver<'a, Vec<CommitId>>,
|
||||
commit_id_resolver: CommitPrefixResolver<'a>,
|
||||
change_id_resolver: ChangePrefixResolver<'a>,
|
||||
}
|
||||
|
||||
impl<'a> DefaultSymbolResolver<'a> {
|
||||
pub fn new(repo: &'a dyn Repo) -> Self {
|
||||
DefaultSymbolResolver {
|
||||
repo,
|
||||
commit_id_resolver: Box::new(|repo, prefix| {
|
||||
repo.index().resolve_commit_id_prefix(prefix)
|
||||
}),
|
||||
change_id_resolver: Box::new(|repo, prefix| repo.resolve_change_id_prefix(prefix)),
|
||||
commit_id_resolver: Default::default(),
|
||||
change_id_resolver: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_commit_id_resolver(
|
||||
mut self,
|
||||
commit_id_resolver: PrefixResolver<'a, CommitId>,
|
||||
) -> Self {
|
||||
self.commit_id_resolver = commit_id_resolver;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_change_id_resolver(
|
||||
mut self,
|
||||
change_id_resolver: PrefixResolver<'a, Vec<CommitId>>,
|
||||
) -> Self {
|
||||
self.change_id_resolver = change_id_resolver;
|
||||
pub fn with_id_prefix_context(mut self, id_prefix_context: &'a IdPrefixContext) -> Self {
|
||||
self.commit_id_resolver.context = Some(id_prefix_context);
|
||||
self.change_id_resolver.context = Some(id_prefix_context);
|
||||
self
|
||||
}
|
||||
|
||||
fn partial_resolvers(&self) -> impl Iterator<Item = &dyn PartialSymbolResolver> {
|
||||
DEFAULT_RESOLVERS.iter().copied()
|
||||
let prefix_resolvers: [&dyn PartialSymbolResolver; 2] =
|
||||
[&self.commit_id_resolver, &self.change_id_resolver];
|
||||
itertools::chain!(DEFAULT_RESOLVERS.iter().copied(), prefix_resolvers)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2201,41 +2250,6 @@ impl SymbolResolver for DefaultSymbolResolver<'_> {
|
|||
return Ok(ids);
|
||||
}
|
||||
}
|
||||
// TODO: Convert prefix resolvers
|
||||
|
||||
// Try to resolve as a commit id.
|
||||
if let Some(prefix) = HexPrefix::new(symbol) {
|
||||
match (self.commit_id_resolver)(self.repo, &prefix) {
|
||||
PrefixResolution::AmbiguousMatch => {
|
||||
return Err(RevsetResolutionError::AmbiguousCommitIdPrefix(
|
||||
symbol.to_owned(),
|
||||
));
|
||||
}
|
||||
PrefixResolution::SingleMatch(id) => {
|
||||
return Ok(vec![id]);
|
||||
}
|
||||
PrefixResolution::NoMatch => {
|
||||
// Fall through
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to resolve as a change id.
|
||||
if let Some(prefix) = to_forward_hex(symbol).as_deref().and_then(HexPrefix::new) {
|
||||
match (self.change_id_resolver)(self.repo, &prefix) {
|
||||
PrefixResolution::AmbiguousMatch => {
|
||||
return Err(RevsetResolutionError::AmbiguousChangeIdPrefix(
|
||||
symbol.to_owned(),
|
||||
));
|
||||
}
|
||||
PrefixResolution::SingleMatch(ids) => {
|
||||
return Ok(ids);
|
||||
}
|
||||
PrefixResolution::NoMatch => {
|
||||
// Fall through
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(make_no_such_symbol_error(self.repo, symbol))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue