The function now returns an iterator over `Result`s, matching
`Operation::parents()`.
I updated callers to also propagate the error where it was trivial.
This also means "all:" is allowed in default revsets (such as "revsets.log"),
but that seems okay. In revset aliases, "all:" isn't allowed because aliases
may be expanded to sub-expression position.
Closes#3654
More tests will be added later as "branch list" templates.
In "log" template, we might want to see the number of "local" commits ahead
of any tracked remotes. It can be implemented later in a similar way (or as a
nested remote_refs list.)
Because template is declarative language, and is evaluated as a tree, there
will be multiple copies of the same RefName object. This patch allows us to
cache ahead/behind counts which will be lazily calculated.
This is a remainder of the previous refactoring series. into_template() could be
implemented as a non-extension method, which allows us to get rid of .clone()
from Literal property extraction. However, there wasn't measurable difference.
Let's not try to overly optimize things. It's probably simpler to switch to
Rc<str> if .clone() really matters.
I considered adding RefTarget template type, but some of the methods naturally
fit to RefName. For example, a conflicted branch name is decorated as "??", so
it makes sense to add branch.conflict() instead of branch.target().conflict().
I'm not pretty sure how many RefName methods we'll need to add to port the
current branch listing, but there will be .tracked(), .tracking_local_present(),
.ahead_by(), and .behind_by().
I'm going to add ref_name.target*() template methods so the commit templater
can be reused for branches/tags templates. RefTarget could be looked up by
(name, kind) pair, but it's simpler to store it in RefName.
Since we have two separate "immutable" calls in the builtin node template, and
user might add a few more to their text template, it seems reasonable to cache
the containing_fn globally.
If we ever implement some sort of ABI for dynamic extension loading, we'll need these underlying APIs to support multiple extensions, so we might as well do that first.
The nightly compiler has several clippy fix-its that, if applied, break the
build. There are various bugs about this, but there isn't enough space in the
margins to detail it all.
Just ignore these on a per-function basis; about 70% of them are just multiple
instances happening inside a single function.
This makes `cargo clippy --workspace --all-targets` run clean, even with the
nightly compiler.
Signed-off-by: Austin Seipp <aseipp@pobox.com>
Change-Id: Ic26a025d3c62b12fbf096171308b56e38f7d1bb9
This allows us to propagate property evaluation error to a string property. For
instance, "s.contains(x ++ y)" will be an error if "y" failed to evaluate,
whereas bare "x ++ y" shouldn't.
The other implementation ideas:
a. add Template::into_string_property() to enable strict evaluation
=> it's tedious to implement it for each printable type
b. pass (formatter, error_handler) arguments separately
=> works, but most implementors don't need error_handler argument
c. pass strict=bool flag around build_*() functions
=> didn't tried, but it would be more complicated than this patch
Because Template trait is now implementation detail of the templater, it
should be okay to use a non-standard formatter wrapper.
Because the CLI error handler now prints error sources in multi-line format,
it doesn't make much sense to render Revset/TemplateParseError differently.
This patch also fixes the source() of the SyntaxError kind. It should be
self.pest_error.source() (= None), not self.pest_error.
IntoTemplate will be cleaned up later. Perhaps, the lifetime parameter can be
removed at this point, but I'm planning to remove the IntoTemplate trait at all.
I think Option<Commit> is the simplest encoding of the log node.
The behavior of an Option type is closer to nullable types rather than the
Option in Rust. I don't think we would want to write opt.map(|x| x.f()) or
opt.unwrap().f(). We can of course add opt?.f() syntax, but it will be a short
for "if(opt, opt.f())"?
Now a compiled template doesn't have a static Context type internally. A
property is basically of "Fn() -> Result<O, _>" type, and a type-erased "self"
variable will be injected as needed.
Template<C> types will be refactored separately.
In short, this enables compilation of template of e.g. Vec<Commit> type by
using CommitTemplateLanguage.
A Template<C> was originally compiled for a specific type C, and invoked as
"Fn(&C) -> _". It was simple and intuitive, but we had to define the context
type C statically. Things got even worse by extensions support because we had
to provide object-safe hook point for each context type C.
This patch basically removes the Context type from compiled templates. The
"self" variable is injected through RefCell<Option<C>> placeholder. A compiled
template knows its "self" type, but the type can be decided per instance, not
per TemplateLanguage type. A drawback is that the "self" variable will have to
be cloned one more time.
The Template<C> abstraction no longer makes sense, and will be split to inner
Template<()> implementations (which usually represent printable types) and the
outer Template<C>.
These .wrap_<type>() functions aren't supposed to capture resources from the
language instance. It was convenient that wrap_() could be called without fully
spelling the language type, but doing that would introduce lifetime issue in
later patches.
I added type alias L to several places because the language type is usually
called L in generic code.
The original plan was to extend the globals table to implement "revset(expr)".
I'm not sure if that's more discoverable than "self.contained_in(revset_expr)"
method, but we can decide that later. Anyways, this patch adds typo suggestion
for global functions.
Prepares for migrating to table-based lookup. It's unlikely that the
implementor handles global function calls differently, but the core doesn't
have an access to the customized symbol table.
I'm going to add generic templating support for basic value types, and
"jj config list -T" will use CommandHelper::parse_template().
CommandHelper::load_template_aliases() is made private instead.
This could be a provided method of the TemplateLanguage trait, but it's
unlikely that this method would have to be customized by implementors. And
I'm going to add thin wrapper method to CommandHelper, so no users would
write language.parse(..) anyway.
I'm going to split commit/operation_templater::parse() into two parts, and
the first half will be Commit/OperationTemplateLanguage::new(..). This patch
also makes CommitTemplateLanguage::wrap_() functions public because extension
methods should be able to return property of these types.