#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum StringInterpPart {
Literal(String),
Expr(Expr),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Annotation {
pub name: String,
pub body: Vec<Entry>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Module {
pub amends: Option<String>,
pub extends: Option<String>,
pub imports: Vec<Import>,
pub annotations: Vec<Annotation>,
pub body: Vec<Entry>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Import {
pub uri: String,
pub alias: Option<String>,
pub is_glob: bool,
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum Entry {
Property(Property),
DynProperty(Expr, Expr),
ForGenerator(ForGenerator),
WhenGenerator(WhenGenerator),
Spread(Expr),
Elem(Expr),
ClassDef(String, Vec<Modifier>, Option<String>, Vec<Entry>),
TypeAlias(String, TypeExpr),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Property {
pub annotations: Vec<Annotation>,
pub modifiers: Vec<Modifier>,
pub name: String,
pub type_ann: Option<TypeExpr>,
pub value: Option<Expr>,
pub body: Option<Vec<Entry>>,
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum Modifier {
Local,
Const,
Fixed,
Hidden,
Abstract,
Open,
External,
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum TypeExpr {
Named(String),
Nullable(Box<TypeExpr>),
Union(Vec<TypeExpr>),
Generic(String, Vec<TypeExpr>),
Constrained(String, Box<Expr>),
}
pub(super) fn type_expr_runtime_name(ty: &TypeExpr) -> String {
match ty {
TypeExpr::Named(name) => name.clone(),
TypeExpr::Nullable(inner) => format!("{}?", type_expr_runtime_name(inner)),
TypeExpr::Union(_) => "Any".to_string(),
TypeExpr::Generic(name, args) => format!(
"{}<{}>",
name,
args.iter()
.map(type_expr_runtime_name)
.collect::<Vec<_>>()
.join(", ")
),
TypeExpr::Constrained(name, _) => name.clone(),
}
}
pub(super) fn infer_method_return_new(expr: &mut Expr, return_type: &TypeExpr) {
match expr {
Expr::New(None, entries, _) => {
*expr = Expr::InferredNew(return_type.clone(), std::mem::take(entries));
}
Expr::If(_, then_expr, else_expr) => {
infer_method_return_new(then_expr, return_type);
infer_method_return_new(else_expr, return_type);
}
Expr::Let(_, _, body) | Expr::Trace(body) => infer_method_return_new(body, return_type),
_ => {}
}
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum Expr {
Null,
Bool(bool),
Int(i64),
Float(f64),
String(String),
Ident(String),
New(Option<String>, Vec<Entry>, Vec<String>),
InferredNew(TypeExpr, Vec<Entry>),
Field(Box<Expr>, String),
Index(Box<Expr>, Box<Expr>),
Call(Box<Expr>, Vec<Expr>),
If(Box<Expr>, Box<Expr>, Box<Expr>),
Let(String, Box<Expr>, Box<Expr>),
Is(Box<Expr>, TypeExpr),
As(Box<Expr>, TypeExpr),
Binop(BinOp, Box<Expr>, Box<Expr>),
Unop(UnOp, Box<Expr>),
ObjectBody(Vec<Entry>),
StringInterpolation(Vec<StringInterpPart>),
NullSafeField(Box<Expr>, String),
Lambda(Vec<String>, Box<Expr>),
Throw(Box<Expr>),
Trace(Box<Expr>),
Read(Box<Expr>),
ReadOrNull(Box<Expr>),
Import(String, String),
ImportGlob(String, String),
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Mod,
IntDiv,
Pow,
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
And,
Or,
NullCoalesce,
Pipe,
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum UnOp {
Neg,
Not,
NonNull,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ForGenerator {
pub key_var: Option<String>,
pub val_var: String,
pub collection: Expr,
pub body: Vec<Entry>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct WhenGenerator {
pub condition: Expr,
pub body: Vec<Entry>,
pub else_body: Option<Vec<Entry>>,
}