Parse union types of arrays and objects (#7213)

Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
Nick Cameron
2025-05-28 07:42:42 +12:00
committed by GitHub
parent 8f4327ab6b
commit dba0173cc3
4 changed files with 22 additions and 17 deletions

View File

@ -150,7 +150,7 @@ impl RuntimeType {
} }
Type::Union { tys } => tys Type::Union { tys } => tys
.into_iter() .into_iter()
.map(|t| Self::from_parsed_primitive(t.inner, exec_state, source_range)) .map(|t| Self::from_parsed(t.inner, exec_state, source_range))
.collect::<Result<Vec<_>, CompilationError>>() .collect::<Result<Vec<_>, CompilationError>>()
.map(RuntimeType::Union), .map(RuntimeType::Union),
Type::Object { properties } => properties Type::Object { properties } => properties

View File

@ -3320,7 +3320,7 @@ pub enum Type {
}, },
// Union/enum types // Union/enum types
Union { Union {
tys: NodeList<PrimitiveType>, tys: NodeList<Type>,
}, },
// An object type. // An object type.
Object { Object {

View File

@ -2833,7 +2833,22 @@ fn record_ty_field(i: &mut TokenSlice) -> ModalResult<(Node<Identifier>, Node<Ty
/// Parse a type in various positions. /// Parse a type in various positions.
fn type_(i: &mut TokenSlice) -> ModalResult<Node<Type>> { fn type_(i: &mut TokenSlice) -> ModalResult<Node<Type>> {
let type_ = alt(( separated(1.., type_not_union, pipe_sep)
.map(|mut tys: Vec<_>| {
if tys.len() == 1 {
tys.pop().unwrap()
} else {
let start = tys[0].start;
let module_id = tys[0].module_id;
let end = tys.last().unwrap().end;
Node::new(Type::Union { tys }, start, end, module_id)
}
})
.parse_next(i)
}
fn type_not_union(i: &mut TokenSlice) -> ModalResult<Node<Type>> {
alt((
// Object types // Object types
( (
open_brace, open_brace,
@ -2852,21 +2867,10 @@ fn type_(i: &mut TokenSlice) -> ModalResult<Node<Type>> {
}), }),
// Array types // Array types
array_type, array_type,
// Primitive or union types // Primitive types
separated(1.., primitive_type, pipe_sep).map(|mut tys: Vec<_>| { primitive_type.map(|t| t.map(Type::Primitive)),
if tys.len() == 1 {
tys.pop().unwrap().map(Type::Primitive)
} else {
let start = tys[0].start;
let module_id = tys[0].module_id;
let end = tys.last().unwrap().end;
Node::new(Type::Union { tys }, start, end, module_id)
}
}),
)) ))
.parse_next(i)?; .parse_next(i)
Ok(type_)
} }
fn primitive_type(i: &mut TokenSlice) -> ModalResult<Node<PrimitiveType>> { fn primitive_type(i: &mut TokenSlice) -> ModalResult<Node<PrimitiveType>> {

View File

@ -2453,6 +2453,7 @@ thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
@(impl = primitive) @(impl = primitive)
export type bar(unit, baz) export type bar(unit, baz)
type baz = Foo | Bar type baz = Foo | Bar
type UnionOfArrays = [Foo] | [Bar] | Foo | { a: T, b: Foo | Bar | [Baz] }
"#; "#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap(); let program = crate::parsing::top_level_parse(some_program_string).unwrap();
let recasted = program.recast(&Default::default(), 0); let recasted = program.recast(&Default::default(), 0);