use proc_macro2::{Span as Span2, TokenStream as TokenStream2};
use syn::punctuated::Punctuated;
use syn::token::{Else, FatArrow, If, Match, Mut};
use syn::{AngleBracketedGenericArguments, Expr, ExprClosure, Ident, Pat, Path, Type, token};
use crate::args::Args;
mod codegen;
mod parse;
mod parse_util;
mod span;
#[derive(Debug)]
pub(super) struct ViewWidgets {
pub(super) span: Span2,
pub(super) top_level_widgets: Vec<TopLevelWidget>,
}
#[derive(Debug)]
pub(super) struct TopLevelWidget {
pub(super) root_attr: Option<Ident>,
pub(super) inner: Widget,
}
#[derive(Debug)]
enum PropertyType {
Assign(AssignProperty),
SignalHandler(SignalHandler),
Widget(Widget),
ConditionalWidget(ConditionalWidget),
ParseError(ParseError),
}
#[derive(Debug)]
enum ParseError {
Ident((Ident, TokenStream2)),
Path((Path, TokenStream2)),
Generic(TokenStream2),
}
#[derive(Debug)]
enum AssignPropertyAttr {
None,
Watch {
skip_init: Option<Ident>,
},
Track {
track_expr: TokenStream2,
skip_init: Option<Ident>,
paste_model: bool,
},
}
#[derive(Debug)]
struct AssignProperty {
attr: AssignPropertyAttr,
args: Option<Args<Expr>>,
expr: Expr,
optional_assign: bool,
iterative: bool,
block_signals: Vec<Ident>,
chain: Option<Box<Expr>>,
}
#[derive(Debug)]
struct SignalHandler {
inner: SignalHandlerVariant,
handler_id: Option<Ident>,
}
#[derive(Debug)]
enum SignalHandlerVariant {
Expr(Expr),
Closure(ClosureSignalHandler),
}
#[derive(Debug)]
struct ClosureSignalHandler {
closure: ExprClosure,
args: Option<Args<Expr>>,
}
#[derive(Debug)]
enum PropertyName {
Ident(Ident),
Path(Path),
RelmContainerExtAssign(Span2),
}
#[derive(Debug)]
struct Property {
name: PropertyName,
ty: PropertyType,
}
#[derive(Debug, Default)]
struct Properties {
properties: Vec<Property>,
}
#[derive(Debug)]
struct WidgetFunc {
path: Path,
args: Option<Punctuated<Expr, token::Comma>>,
method_chain: Option<Punctuated<WidgetFuncMethod, token::Dot>>,
ty: Option<Box<Type>>,
}
#[derive(Debug)]
struct WidgetFuncMethod {
ident: Ident,
turbofish: Option<AngleBracketedGenericArguments>,
args: Option<Punctuated<Expr, token::Comma>>,
}
#[derive(Debug)]
pub(super) struct Widget {
doc_attr: Option<TokenStream2>,
attr: WidgetAttr,
template_attr: WidgetTemplateAttr,
pub(super) mutable: Option<Mut>,
pub(super) name: Ident,
name_assigned_by_user: bool,
func: WidgetFunc,
args: Option<Args<Expr>>,
properties: Properties,
assign_wrapper: Option<Path>,
ref_token: Option<token::And>,
deref_token: Option<token::Star>,
returned_widget: Option<ReturnedWidget>,
}
#[derive(Debug, PartialEq)]
enum WidgetAttr {
None,
Local,
LocalRef,
}
#[derive(Debug, PartialEq)]
enum WidgetTemplateAttr {
None,
Template,
TemplateChild,
}
#[derive(Debug)]
struct ReturnedWidget {
name: Ident,
ty: Option<Path>,
properties: Properties,
is_optional: bool,
}
#[derive(Debug)]
struct ConditionalWidget {
doc_attr: Option<TokenStream2>,
transition: Option<Ident>,
assign_wrapper: Option<Path>,
name: Ident,
args: Option<Args<Expr>>,
branches: ConditionalBranches,
}
#[derive(Debug)]
enum ConditionalBranches {
If(Vec<IfBranch>),
Match((Match, Box<Expr>, Vec<MatchArm>)),
}
#[derive(Debug)]
enum IfCondition {
If(If, Expr),
ElseIf(Else, If, Expr),
Else(Else),
}
#[derive(Debug)]
struct IfBranch {
cond: IfCondition,
widget: Widget,
}
#[derive(Debug)]
struct MatchArm {
pattern: Pat,
guard: Option<(If, Box<Expr>)>,
arrow: FatArrow,
widget: Widget,
}
enum Attr {
Doc(TokenStream2),
Local(Ident),
LocalRef(Ident),
Root(Ident),
Iterate(Ident),
Watch(Ident, Option<Ident>),
Track(Ident, Option<Ident>, Option<Box<Expr>>),
BlockSignal(Ident, Vec<Ident>),
Name(Ident, Ident),
Transition(Ident, Ident),
Wrap(Ident, Path),
Chain(Ident, Box<Expr>),
Template(Ident),
TemplateChild(Ident),
}
struct Attrs {
inner: Vec<Attr>,
}