mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-09 05:58:55 +00:00
dsl_util: add trait that constructs ExpressionKind of basic AST node types
This isn't fancy, but we'll need some generic way to return either original or substituted expression node. I think this is the simplest abstraction.
This commit is contained in:
parent
b0913342b1
commit
cf6357459d
2 changed files with 31 additions and 6 deletions
|
@ -17,8 +17,8 @@ use std::{error, mem};
|
|||
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::dsl_util::{
|
||||
self, collect_similar, AliasDeclaration, AliasDeclarationParser, AliasId, AliasesMap,
|
||||
InvalidArguments, StringLiteralParser,
|
||||
self, collect_similar, AliasDeclaration, AliasDeclarationParser, AliasExpandableExpression,
|
||||
AliasId, AliasesMap, InvalidArguments, StringLiteralParser,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use pest::iterators::{Pair, Pairs};
|
||||
|
@ -262,6 +262,20 @@ pub enum ExpressionKind<'i> {
|
|||
AliasExpanded(AliasId<'i>, Box<ExpressionNode<'i>>),
|
||||
}
|
||||
|
||||
impl<'i> AliasExpandableExpression<'i> for ExpressionKind<'i> {
|
||||
fn identifier(name: &'i str) -> Self {
|
||||
ExpressionKind::Identifier(name)
|
||||
}
|
||||
|
||||
fn function_call(function: Box<FunctionCallNode<'i>>) -> Self {
|
||||
ExpressionKind::FunctionCall(function)
|
||||
}
|
||||
|
||||
fn alias_expanded(id: AliasId<'i>, subst: Box<ExpressionNode<'i>>) -> Self {
|
||||
ExpressionKind::AliasExpanded(id, subst)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum UnaryOp {
|
||||
/// `!`
|
||||
|
@ -547,7 +561,7 @@ pub fn expand_aliases<'i>(
|
|||
// Parsed defn could be cached if needed.
|
||||
parse_template(defn)
|
||||
.and_then(|node| expand_node(node, expanding_state))
|
||||
.map(|node| ExpressionKind::AliasExpanded(id, Box::new(node)))
|
||||
.map(|node| ExpressionKind::alias_expanded(id, Box::new(node)))
|
||||
.map_err(|e| e.within_alias_expansion(id, span))
|
||||
}
|
||||
|
||||
|
@ -581,12 +595,13 @@ pub fn expand_aliases<'i>(
|
|||
let kind = match kind {
|
||||
ExpressionKind::Identifier(name) => {
|
||||
if let Some(subst) = state.locals.get(name) {
|
||||
ExpressionKind::AliasExpanded(AliasId::Parameter(name), Box::new(subst.clone()))
|
||||
let id = AliasId::Parameter(name);
|
||||
ExpressionKind::alias_expanded(id, Box::new(subst.clone()))
|
||||
} else if let Some((id, defn)) = state.aliases_map.get_symbol(name) {
|
||||
let locals = HashMap::new(); // Don't spill out the current scope
|
||||
expand_defn(id, defn, &locals, span, state)?
|
||||
} else {
|
||||
kind
|
||||
ExpressionKind::identifier(name)
|
||||
}
|
||||
}
|
||||
ExpressionKind::Boolean(_) | ExpressionKind::Integer(_) | ExpressionKind::String(_) => {
|
||||
|
@ -619,7 +634,7 @@ pub fn expand_aliases<'i>(
|
|||
expand_defn(id, defn, &locals, span, state)?
|
||||
} else {
|
||||
let function = Box::new(expand_function_call(*function, state)?);
|
||||
ExpressionKind::FunctionCall(function)
|
||||
ExpressionKind::function_call(function)
|
||||
}
|
||||
}
|
||||
ExpressionKind::MethodCall(method) => {
|
||||
|
|
|
@ -266,6 +266,16 @@ pub trait AliasDeclarationParser {
|
|||
fn parse_declaration(&self, source: &str) -> Result<AliasDeclaration, Self::Error>;
|
||||
}
|
||||
|
||||
/// Expression item that supports alias substitution.
|
||||
pub trait AliasExpandableExpression<'i>: Sized {
|
||||
/// Wraps identifier.
|
||||
fn identifier(name: &'i str) -> Self;
|
||||
/// Wraps function call.
|
||||
fn function_call(function: Box<FunctionCallNode<'i, Self>>) -> Self;
|
||||
/// Wraps substituted expression.
|
||||
fn alias_expanded(id: AliasId<'i>, subst: Box<ExpressionNode<'i, Self>>) -> Self;
|
||||
}
|
||||
|
||||
/// Collects similar names from the `candidates` list.
|
||||
pub fn collect_similar<I>(name: &str, candidates: I) -> Vec<String>
|
||||
where
|
||||
|
|
Loading…
Reference in a new issue