ok/jj
1
0
Fork 0
forked from mirrors/jj

revset: rewrite match table of builtin functions as HashMap

So that we can build a list of function names.
This commit is contained in:
Yuya Nishihara 2023-03-22 18:15:18 +09:00
parent 9ed537b3e8
commit d3d8afc77b

View file

@ -711,52 +711,57 @@ fn parse_function_expression(
state.with_alias_expanding(id, &locals, primary_span, |state| {
parse_program(defn, state)
})
} else if let Some(func) = BUILTIN_FUNCTION_MAP.get(name) {
func(name, arguments_pair, state)
} else {
parse_builtin_function(name_pair, arguments_pair, state)
Err(RevsetParseError::with_span(
RevsetParseErrorKind::NoSuchFunction(name.to_owned()),
name_pair.as_span(),
))
}
}
fn parse_builtin_function(
name_pair: Pair<Rule>,
arguments_pair: Pair<Rule>,
state: ParseState,
) -> Result<Rc<RevsetExpression>, RevsetParseError> {
let name = name_pair.as_str();
match name {
"parents" => {
type RevsetFunction =
fn(&str, Pair<Rule>, ParseState) -> Result<Rc<RevsetExpression>, RevsetParseError>;
static BUILTIN_FUNCTION_MAP: Lazy<HashMap<&'static str, RevsetFunction>> = Lazy::new(|| {
// Not using maplit::hashmap!{} or custom declarative macro here because
// code completion inside macro is quite restricted.
let mut map: HashMap<&'static str, RevsetFunction> = HashMap::new();
map.insert("parents", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let expression = parse_expression_rule(arg.into_inner(), state)?;
Ok(expression.parents())
}
"children" => {
});
map.insert("children", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let expression = parse_expression_rule(arg.into_inner(), state)?;
Ok(expression.children())
}
"ancestors" => {
});
map.insert("ancestors", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let expression = parse_expression_rule(arg.into_inner(), state)?;
Ok(expression.ancestors())
}
"descendants" => {
});
map.insert("descendants", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let expression = parse_expression_rule(arg.into_inner(), state)?;
Ok(expression.descendants())
}
"connected" => {
});
map.insert("connected", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let candidates = parse_expression_rule(arg.into_inner(), state)?;
Ok(candidates.connected())
}
"none" => {
});
map.insert("none", |name, arguments_pair, _state| {
expect_no_arguments(name, arguments_pair)?;
Ok(RevsetExpression::none())
}
"all" => {
});
map.insert("all", |name, arguments_pair, _state| {
expect_no_arguments(name, arguments_pair)?;
Ok(RevsetExpression::all())
}
"heads" => {
});
map.insert("heads", |name, arguments_pair, state| {
let ([], [opt_arg]) = expect_arguments(name, arguments_pair)?;
if let Some(arg) = opt_arg {
let candidates = parse_expression_rule(arg.into_inner(), state)?;
@ -764,17 +769,17 @@ fn parse_builtin_function(
} else {
Ok(RevsetExpression::visible_heads())
}
}
"roots" => {
});
map.insert("roots", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let candidates = parse_expression_rule(arg.into_inner(), state)?;
Ok(candidates.roots())
}
"public_heads" => {
});
map.insert("public_heads", |name, arguments_pair, _state| {
expect_no_arguments(name, arguments_pair)?;
Ok(RevsetExpression::public_heads())
}
"branches" => {
});
map.insert("branches", |name, arguments_pair, state| {
let ([], [opt_arg]) = expect_arguments(name, arguments_pair)?;
let needle = if let Some(arg) = opt_arg {
parse_function_argument_to_string(name, arg, state)?
@ -782,8 +787,8 @@ fn parse_builtin_function(
"".to_owned()
};
Ok(RevsetExpression::branches(needle))
}
"remote_branches" => {
});
map.insert("remote_branches", |name, arguments_pair, state| {
let ([], [branch_opt_arg, remote_opt_arg]) =
expect_named_arguments(name, &["", "remote"], arguments_pair)?;
let branch_needle = if let Some(branch_arg) = branch_opt_arg {
@ -800,51 +805,51 @@ fn parse_builtin_function(
branch_needle,
remote_needle,
))
}
"tags" => {
});
map.insert("tags", |name, arguments_pair, _state| {
expect_no_arguments(name, arguments_pair)?;
Ok(RevsetExpression::tags())
}
"git_refs" => {
});
map.insert("git_refs", |name, arguments_pair, _state| {
expect_no_arguments(name, arguments_pair)?;
Ok(RevsetExpression::git_refs())
}
"git_head" => {
});
map.insert("git_head", |name, arguments_pair, _state| {
expect_no_arguments(name, arguments_pair)?;
Ok(RevsetExpression::git_head())
}
"merges" => {
});
map.insert("merges", |name, arguments_pair, _state| {
expect_no_arguments(name, arguments_pair)?;
Ok(RevsetExpression::filter(
RevsetFilterPredicate::ParentCount(2..u32::MAX),
))
}
"description" => {
});
map.insert("description", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let needle = parse_function_argument_to_string(name, arg, state)?;
Ok(RevsetExpression::filter(
RevsetFilterPredicate::Description(needle),
))
}
"author" => {
});
map.insert("author", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let needle = parse_function_argument_to_string(name, arg, state)?;
Ok(RevsetExpression::filter(RevsetFilterPredicate::Author(
needle,
)))
}
"committer" => {
});
map.insert("committer", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let needle = parse_function_argument_to_string(name, arg, state)?;
Ok(RevsetExpression::filter(RevsetFilterPredicate::Committer(
needle,
)))
}
"empty" => {
});
map.insert("empty", |name, arguments_pair, _state| {
expect_no_arguments(name, arguments_pair)?;
Ok(RevsetExpression::filter(RevsetFilterPredicate::File(None)).negated())
}
"file" => {
});
map.insert("file", |name, arguments_pair, state| {
if let Some(ctx) = state.workspace_ctx {
let arguments_span = arguments_pair.as_span();
let paths: Vec<_> = arguments_pair
@ -880,18 +885,14 @@ fn parse_builtin_function(
RevsetParseErrorKind::FsPathWithoutWorkspace,
))
}
}
"present" => {
});
map.insert("present", |name, arguments_pair, state| {
let arg = expect_one_argument(name, arguments_pair)?;
let expression = parse_expression_rule(arg.into_inner(), state)?;
Ok(Rc::new(RevsetExpression::Present(expression)))
}
_ => Err(RevsetParseError::with_span(
RevsetParseErrorKind::NoSuchFunction(name.to_owned()),
name_pair.as_span(),
)),
}
}
});
map
});
type OptionalArg<'i> = Option<Pair<'i, Rule>>;