Skip to content

Commit 85d9470

Browse files
committed
refactor: Allow the aliases map to map to arbitrary types.
For jj-vcs#3673, we will have aliases such as: ```toml 'upload(revision)' = [ ["fix", "-r", "$revision"], ["lint", "-r", "$revision"], ["git", "push", "-r", "$revision"], ] ``` Template aliases: 1) Start as Config::Value 2) Are converted to String 3) Are placed in the alias map 4) Expand to a TemplateExpression type via expand_defn. However, command aliases: 1) Start as Config::Value 2) Are converted to Vec<Vec<String>> 3) Are placed in an alias map 4) Do not expand Thus, AliasesMap will need to support non-string values.
1 parent 3d26af8 commit 85d9470

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

cli/src/template_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ pub fn parse_template(template_text: &str) -> TemplateParseResult<ExpressionNode
568568
}
569569
}
570570

571-
pub type TemplateAliasesMap = AliasesMap<TemplateAliasParser>;
571+
pub type TemplateAliasesMap = AliasesMap<TemplateAliasParser, String>;
572572

573573
#[derive(Clone, Debug, Default)]
574574
pub struct TemplateAliasParser;

lib/src/dsl_util.rs

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
use std::array;
1818
use std::collections::HashMap;
19+
use std::ops::Deref;
1920
use std::fmt;
2021
use std::slice;
2122

@@ -423,16 +424,28 @@ impl<R: RuleType> StringLiteralParser<R> {
423424
}
424425

425426
/// Map of symbol and function aliases.
426-
#[derive(Clone, Debug, Default)]
427-
pub struct AliasesMap<P> {
428-
symbol_aliases: HashMap<String, String>,
427+
#[derive(Clone, Debug)]
428+
pub struct AliasesMap<P, V: Deref> {
429+
symbol_aliases: HashMap<String, V>,
429430
// name: [(params, defn)] (sorted by arity)
430-
function_aliases: HashMap<String, Vec<(Vec<String>, String)>>,
431+
function_aliases: HashMap<String, Vec<(Vec<String>, V)>>,
431432
// Parser type P helps prevent misuse of AliasesMap of different language.
432433
parser: P,
433434
}
434435

435-
impl<P> AliasesMap<P> {
436+
// Unfortunately, #[derive(Default)] doesn't work correctly since V isn't
437+
// Default. https://stackoverflow.com/questions/59538071/the-trait-bound-t-stddefaultdefault-is-not-satisfied-when-using-phantomda
438+
impl<P: Default, V: Deref> Default for AliasesMap<P, V> {
439+
fn default() -> Self {
440+
Self {
441+
symbol_aliases: Default::default(),
442+
function_aliases: Default::default(),
443+
parser: Default::default(),
444+
}
445+
}
446+
}
447+
448+
impl<P, V: Deref> AliasesMap<P, V> {
436449
/// Creates an empty aliases map with default-constructed parser.
437450
pub fn new() -> Self
438451
where
@@ -445,7 +458,7 @@ impl<P> AliasesMap<P> {
445458
///
446459
/// Returns error if `decl` is invalid. The `defn` part isn't checked. A bad
447460
/// `defn` will be reported when the alias is substituted.
448-
pub fn insert(&mut self, decl: impl AsRef<str>, defn: impl Into<String>) -> Result<(), P::Error>
461+
pub fn insert(&mut self, decl: impl AsRef<str>, defn: impl Into<V>) -> Result<(), P::Error>
449462
where
450463
P: AliasDeclarationParser,
451464
{
@@ -475,46 +488,53 @@ impl<P> AliasesMap<P> {
475488
}
476489

477490
/// Looks up symbol alias by name. Returns identifier and definition text.
478-
pub fn get_symbol(&self, name: &str) -> Option<(AliasId<'_>, &str)> {
491+
pub fn get_symbol(&self, name: &str) -> Option<(AliasId<'_>, &<V as Deref>::Target)> {
479492
self.symbol_aliases
480493
.get_key_value(name)
481-
.map(|(name, defn)| (AliasId::Symbol(name), defn.as_ref()))
494+
.map(|(name, defn)| (AliasId::Symbol(name), defn.deref()))
482495
}
483496

484497
/// Looks up function alias by name and arity. Returns identifier, list of
485498
/// parameter names, and definition text.
486-
pub fn get_function(&self, name: &str, arity: usize) -> Option<(AliasId<'_>, &[String], &str)> {
499+
pub fn get_function(
500+
&self,
501+
name: &str,
502+
arity: usize,
503+
) -> Option<(AliasId<'_>, &[String], &<V as Deref>::Target)> {
487504
let overloads = self.get_function_overloads(name)?;
488505
overloads.find_by_arity(arity)
489506
}
490507

491508
/// Looks up function aliases by name.
492-
fn get_function_overloads(&self, name: &str) -> Option<AliasFunctionOverloads<'_>> {
509+
fn get_function_overloads(&self, name: &str) -> Option<AliasFunctionOverloads<'_, V>> {
493510
let (name, overloads) = self.function_aliases.get_key_value(name)?;
494511
Some(AliasFunctionOverloads { name, overloads })
495512
}
496513
}
497514

498515
#[derive(Clone, Copy, Debug)]
499-
struct AliasFunctionOverloads<'a> {
516+
struct AliasFunctionOverloads<'a, V: Deref> {
500517
name: &'a String,
501-
overloads: &'a Vec<(Vec<String>, String)>,
518+
overloads: &'a Vec<(Vec<String>, V)>,
502519
}
503520

504-
impl<'a> AliasFunctionOverloads<'a> {
505-
fn arities(self) -> impl DoubleEndedIterator<Item = usize> + ExactSizeIterator + 'a {
521+
impl<'a, V: Deref> AliasFunctionOverloads<'a, V> {
522+
fn arities(&self) -> impl DoubleEndedIterator<Item = usize> + ExactSizeIterator + 'a {
506523
self.overloads.iter().map(|(params, _)| params.len())
507524
}
508525

509-
fn min_arity(self) -> usize {
526+
fn min_arity(&self) -> usize {
510527
self.arities().next().unwrap()
511528
}
512529

513-
fn max_arity(self) -> usize {
530+
fn max_arity(&self) -> usize {
514531
self.arities().next_back().unwrap()
515532
}
516533

517-
fn find_by_arity(self, arity: usize) -> Option<(AliasId<'a>, &'a [String], &'a str)> {
534+
fn find_by_arity(
535+
&self,
536+
arity: usize,
537+
) -> Option<(AliasId<'a>, &'a [String], &'a <V as Deref>::Target)> {
518538
let index = self
519539
.overloads
520540
.binary_search_by_key(&arity, |(params, _)| params.len())
@@ -609,7 +629,7 @@ pub trait AliasExpandError: Sized {
609629
#[derive(Debug)]
610630
struct AliasExpander<'i, T, P> {
611631
/// Alias symbols and functions that are globally available.
612-
aliases_map: &'i AliasesMap<P>,
632+
aliases_map: &'i AliasesMap<P, String>,
613633
/// Stack of aliases and local parameters currently expanding.
614634
states: Vec<AliasExpandingState<'i, T>>,
615635
}
@@ -708,7 +728,7 @@ where
708728
/// Expands aliases recursively.
709729
pub fn expand_aliases<'i, T, P>(
710730
node: ExpressionNode<'i, T>,
711-
aliases_map: &'i AliasesMap<P>,
731+
aliases_map: &'i AliasesMap<P, String>,
712732
) -> Result<ExpressionNode<'i, T>, P::Error>
713733
where
714734
T: AliasExpandableExpression<'i> + Clone,

lib/src/revset_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ fn parse_function_call_node(pair: Pair<Rule>) -> Result<FunctionCallNode, Revset
717717
})
718718
}
719719

720-
pub type RevsetAliasesMap = AliasesMap<RevsetAliasParser>;
720+
pub type RevsetAliasesMap = AliasesMap<RevsetAliasParser, String>;
721721

722722
#[derive(Clone, Debug, Default)]
723723
pub struct RevsetAliasParser;

0 commit comments

Comments
 (0)