Add ListItem type for Expr::List (#12529)

# Description
This PR adds a `ListItem` enum to our set of AST types. It encodes the
two possible expressions inside of list expression: a singular item or a
spread. This is similar to the existing `RecordItem` enum. Adding
`ListItem` allows us to remove the existing `Expr::Spread` case which
was previously used for list spreads. As a consequence, this guarantees
(via the type system) that spreads can only ever occur inside lists,
records, or as command args.

This PR also does a little bit of cleanup in relevant parser code.
This commit is contained in:
Ian Manske
2024-04-18 11:21:05 +00:00
committed by GitHub
parent 57b0c722c6
commit 6ccd547d81
8 changed files with 179 additions and 133 deletions

View File

@@ -1,7 +1,8 @@
use nu_protocol::{
ast::{
Argument, Block, Expr, Expression, ExternalArgument, ImportPatternMember, MatchPattern,
PathMember, Pattern, Pipeline, PipelineElement, PipelineRedirection, RecordItem,
Argument, Block, Expr, Expression, ExternalArgument, ImportPatternMember, ListItem,
MatchPattern, PathMember, Pattern, Pipeline, PipelineElement, PipelineRedirection,
RecordItem,
},
engine::StateWorkingSet,
DeclId, Span, VarId,
@@ -377,20 +378,31 @@ pub fn flatten_expression(
let mut last_end = outer_span.start;
let mut output = vec![];
for l in list {
let flattened = flatten_expression(working_set, l);
for item in list {
match item {
ListItem::Item(expr) => {
let flattened = flatten_expression(working_set, expr);
if let Some(first) = flattened.first() {
if first.0.start > last_end {
output.push((Span::new(last_end, first.0.start), FlatShape::List));
if let Some(first) = flattened.first() {
if first.0.start > last_end {
output.push((Span::new(last_end, first.0.start), FlatShape::List));
}
}
if let Some(last) = flattened.last() {
last_end = last.0.end;
}
output.extend(flattened);
}
ListItem::Spread(_, expr) => {
let mut output = vec![(
Span::new(expr.span.start, expr.span.start + 3),
FlatShape::Operator,
)];
output.extend(flatten_expression(working_set, expr));
}
}
if let Some(last) = flattened.last() {
last_end = last.0.end;
}
output.extend(flattened);
}
if last_end < outer_span.end {
@@ -545,15 +557,6 @@ pub fn flatten_expression(
Expr::VarDecl(var_id) => {
vec![(expr.span, FlatShape::VarDecl(*var_id))]
}
Expr::Spread(inner_expr) => {
let mut output = vec![(
Span::new(expr.span.start, expr.span.start + 3),
FlatShape::Operator,
)];
output.extend(flatten_expression(working_set, inner_expr));
output
}
}
}