2020-02-27 04:07:26 -06:00
|
|
|
//! Defines input for code generation process.
|
|
|
|
|
2020-01-03 13:37:02 -06:00
|
|
|
pub(crate) struct KindsSrc<'a> {
|
|
|
|
pub(crate) punct: &'a [(&'a str, &'a str)],
|
|
|
|
pub(crate) keywords: &'a [&'a str],
|
|
|
|
pub(crate) contextual_keywords: &'a [&'a str],
|
|
|
|
pub(crate) literals: &'a [&'a str],
|
|
|
|
pub(crate) tokens: &'a [&'a str],
|
|
|
|
pub(crate) nodes: &'a [&'a str],
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
|
|
|
|
punct: &[
|
2020-04-10 10:06:57 -05:00
|
|
|
(";", "SEMICOLON"),
|
2020-01-03 13:37:02 -06:00
|
|
|
(",", "COMMA"),
|
|
|
|
("(", "L_PAREN"),
|
|
|
|
(")", "R_PAREN"),
|
|
|
|
("{", "L_CURLY"),
|
|
|
|
("}", "R_CURLY"),
|
|
|
|
("[", "L_BRACK"),
|
|
|
|
("]", "R_BRACK"),
|
|
|
|
("<", "L_ANGLE"),
|
|
|
|
(">", "R_ANGLE"),
|
|
|
|
("@", "AT"),
|
|
|
|
("#", "POUND"),
|
|
|
|
("~", "TILDE"),
|
|
|
|
("?", "QUESTION"),
|
|
|
|
("$", "DOLLAR"),
|
|
|
|
("&", "AMP"),
|
|
|
|
("|", "PIPE"),
|
|
|
|
("+", "PLUS"),
|
|
|
|
("*", "STAR"),
|
|
|
|
("/", "SLASH"),
|
|
|
|
("^", "CARET"),
|
|
|
|
("%", "PERCENT"),
|
|
|
|
("_", "UNDERSCORE"),
|
|
|
|
(".", "DOT"),
|
2020-04-10 10:06:57 -05:00
|
|
|
("..", "DOT2"),
|
|
|
|
("...", "DOT3"),
|
|
|
|
("..=", "DOT2EQ"),
|
2020-01-03 13:37:02 -06:00
|
|
|
(":", "COLON"),
|
2020-04-10 10:06:57 -05:00
|
|
|
("::", "COLON2"),
|
2020-01-03 13:37:02 -06:00
|
|
|
("=", "EQ"),
|
2020-04-10 10:06:57 -05:00
|
|
|
("==", "EQ2"),
|
2020-01-03 13:37:02 -06:00
|
|
|
("=>", "FAT_ARROW"),
|
2020-04-10 10:06:57 -05:00
|
|
|
("!", "BANG"),
|
2020-01-03 13:37:02 -06:00
|
|
|
("!=", "NEQ"),
|
|
|
|
("-", "MINUS"),
|
|
|
|
("->", "THIN_ARROW"),
|
|
|
|
("<=", "LTEQ"),
|
|
|
|
(">=", "GTEQ"),
|
|
|
|
("+=", "PLUSEQ"),
|
|
|
|
("-=", "MINUSEQ"),
|
|
|
|
("|=", "PIPEEQ"),
|
|
|
|
("&=", "AMPEQ"),
|
|
|
|
("^=", "CARETEQ"),
|
|
|
|
("/=", "SLASHEQ"),
|
|
|
|
("*=", "STAREQ"),
|
|
|
|
("%=", "PERCENTEQ"),
|
2020-04-10 10:06:57 -05:00
|
|
|
("&&", "AMP2"),
|
|
|
|
("||", "PIPE2"),
|
2020-01-03 13:37:02 -06:00
|
|
|
("<<", "SHL"),
|
|
|
|
(">>", "SHR"),
|
|
|
|
("<<=", "SHLEQ"),
|
|
|
|
(">>=", "SHREQ"),
|
|
|
|
],
|
|
|
|
keywords: &[
|
|
|
|
"as", "async", "await", "box", "break", "const", "continue", "crate", "dyn", "else",
|
|
|
|
"enum", "extern", "false", "fn", "for", "if", "impl", "in", "let", "loop", "macro",
|
|
|
|
"match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super",
|
|
|
|
"trait", "true", "try", "type", "unsafe", "use", "where", "while",
|
|
|
|
],
|
2020-04-03 14:12:09 -05:00
|
|
|
contextual_keywords: &["auto", "default", "existential", "union", "raw"],
|
2020-01-03 13:37:02 -06:00
|
|
|
literals: &[
|
|
|
|
"INT_NUMBER",
|
|
|
|
"FLOAT_NUMBER",
|
|
|
|
"CHAR",
|
|
|
|
"BYTE",
|
|
|
|
"STRING",
|
|
|
|
"RAW_STRING",
|
|
|
|
"BYTE_STRING",
|
|
|
|
"RAW_BYTE_STRING",
|
|
|
|
],
|
|
|
|
tokens: &[
|
|
|
|
"ERROR",
|
|
|
|
"IDENT",
|
|
|
|
"WHITESPACE",
|
|
|
|
"LIFETIME",
|
|
|
|
"COMMENT",
|
|
|
|
"SHEBANG",
|
|
|
|
"L_DOLLAR",
|
|
|
|
"R_DOLLAR",
|
|
|
|
],
|
|
|
|
nodes: &[
|
|
|
|
"SOURCE_FILE",
|
|
|
|
"STRUCT_DEF",
|
|
|
|
"UNION_DEF",
|
|
|
|
"ENUM_DEF",
|
|
|
|
"FN_DEF",
|
|
|
|
"RET_TYPE",
|
|
|
|
"EXTERN_CRATE_ITEM",
|
|
|
|
"MODULE",
|
|
|
|
"USE_ITEM",
|
|
|
|
"STATIC_DEF",
|
|
|
|
"CONST_DEF",
|
|
|
|
"TRAIT_DEF",
|
2020-02-29 14:24:40 -06:00
|
|
|
"IMPL_DEF",
|
2020-01-03 13:37:02 -06:00
|
|
|
"TYPE_ALIAS_DEF",
|
|
|
|
"MACRO_CALL",
|
|
|
|
"TOKEN_TREE",
|
|
|
|
"MACRO_DEF",
|
|
|
|
"PAREN_TYPE",
|
|
|
|
"TUPLE_TYPE",
|
|
|
|
"NEVER_TYPE",
|
|
|
|
"PATH_TYPE",
|
|
|
|
"POINTER_TYPE",
|
|
|
|
"ARRAY_TYPE",
|
|
|
|
"SLICE_TYPE",
|
|
|
|
"REFERENCE_TYPE",
|
|
|
|
"PLACEHOLDER_TYPE",
|
|
|
|
"FN_POINTER_TYPE",
|
|
|
|
"FOR_TYPE",
|
|
|
|
"IMPL_TRAIT_TYPE",
|
|
|
|
"DYN_TRAIT_TYPE",
|
2020-02-09 12:57:01 -06:00
|
|
|
"OR_PAT",
|
|
|
|
"PAREN_PAT",
|
2020-01-03 13:37:02 -06:00
|
|
|
"REF_PAT",
|
|
|
|
"BOX_PAT",
|
|
|
|
"BIND_PAT",
|
|
|
|
"PLACEHOLDER_PAT",
|
|
|
|
"DOT_DOT_PAT",
|
|
|
|
"PATH_PAT",
|
|
|
|
"RECORD_PAT",
|
|
|
|
"RECORD_FIELD_PAT_LIST",
|
|
|
|
"RECORD_FIELD_PAT",
|
|
|
|
"TUPLE_STRUCT_PAT",
|
|
|
|
"TUPLE_PAT",
|
|
|
|
"SLICE_PAT",
|
|
|
|
"RANGE_PAT",
|
|
|
|
"LITERAL_PAT",
|
2020-04-03 08:38:42 -05:00
|
|
|
"MACRO_PAT",
|
2020-01-03 13:37:02 -06:00
|
|
|
// atoms
|
|
|
|
"TUPLE_EXPR",
|
|
|
|
"ARRAY_EXPR",
|
|
|
|
"PAREN_EXPR",
|
|
|
|
"PATH_EXPR",
|
|
|
|
"LAMBDA_EXPR",
|
|
|
|
"IF_EXPR",
|
|
|
|
"WHILE_EXPR",
|
|
|
|
"CONDITION",
|
|
|
|
"LOOP_EXPR",
|
|
|
|
"FOR_EXPR",
|
|
|
|
"CONTINUE_EXPR",
|
|
|
|
"BREAK_EXPR",
|
|
|
|
"LABEL",
|
|
|
|
"BLOCK_EXPR",
|
|
|
|
"RETURN_EXPR",
|
|
|
|
"MATCH_EXPR",
|
|
|
|
"MATCH_ARM_LIST",
|
|
|
|
"MATCH_ARM",
|
|
|
|
"MATCH_GUARD",
|
|
|
|
"RECORD_LIT",
|
|
|
|
"RECORD_FIELD_LIST",
|
|
|
|
"RECORD_FIELD",
|
|
|
|
"TRY_BLOCK_EXPR",
|
|
|
|
"BOX_EXPR",
|
|
|
|
// postfix
|
|
|
|
"CALL_EXPR",
|
|
|
|
"INDEX_EXPR",
|
|
|
|
"METHOD_CALL_EXPR",
|
|
|
|
"FIELD_EXPR",
|
|
|
|
"AWAIT_EXPR",
|
|
|
|
"TRY_EXPR",
|
|
|
|
"CAST_EXPR",
|
|
|
|
// unary
|
|
|
|
"REF_EXPR",
|
|
|
|
"PREFIX_EXPR",
|
|
|
|
"RANGE_EXPR", // just weird
|
|
|
|
"BIN_EXPR",
|
|
|
|
"BLOCK",
|
|
|
|
"EXTERN_BLOCK",
|
|
|
|
"EXTERN_ITEM_LIST",
|
|
|
|
"ENUM_VARIANT",
|
|
|
|
"RECORD_FIELD_DEF_LIST",
|
|
|
|
"RECORD_FIELD_DEF",
|
|
|
|
"TUPLE_FIELD_DEF_LIST",
|
|
|
|
"TUPLE_FIELD_DEF",
|
|
|
|
"ENUM_VARIANT_LIST",
|
|
|
|
"ITEM_LIST",
|
|
|
|
"ATTR",
|
|
|
|
"META_ITEM", // not an item actually
|
|
|
|
"USE_TREE",
|
|
|
|
"USE_TREE_LIST",
|
|
|
|
"PATH",
|
|
|
|
"PATH_SEGMENT",
|
|
|
|
"LITERAL",
|
|
|
|
"ALIAS",
|
|
|
|
"VISIBILITY",
|
|
|
|
"WHERE_CLAUSE",
|
|
|
|
"WHERE_PRED",
|
|
|
|
"ABI",
|
|
|
|
"NAME",
|
|
|
|
"NAME_REF",
|
|
|
|
"LET_STMT",
|
|
|
|
"EXPR_STMT",
|
|
|
|
"TYPE_PARAM_LIST",
|
|
|
|
"LIFETIME_PARAM",
|
|
|
|
"TYPE_PARAM",
|
|
|
|
"CONST_PARAM",
|
|
|
|
"TYPE_ARG_LIST",
|
|
|
|
"LIFETIME_ARG",
|
|
|
|
"TYPE_ARG",
|
|
|
|
"ASSOC_TYPE_ARG",
|
2020-01-06 16:59:03 -06:00
|
|
|
"CONST_ARG",
|
2020-01-03 13:37:02 -06:00
|
|
|
"PARAM_LIST",
|
|
|
|
"PARAM",
|
|
|
|
"SELF_PARAM",
|
|
|
|
"ARG_LIST",
|
|
|
|
"TYPE_BOUND",
|
|
|
|
"TYPE_BOUND_LIST",
|
|
|
|
// macro related
|
|
|
|
"MACRO_ITEMS",
|
|
|
|
"MACRO_STMTS",
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
pub(crate) struct AstSrc<'a> {
|
2020-04-10 08:53:09 -05:00
|
|
|
pub(crate) tokens: &'a [&'a str],
|
2020-01-03 13:37:02 -06:00
|
|
|
pub(crate) nodes: &'a [AstNodeSrc<'a>],
|
|
|
|
pub(crate) enums: &'a [AstEnumSrc<'a>],
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) struct AstNodeSrc<'a> {
|
|
|
|
pub(crate) name: &'a str,
|
|
|
|
pub(crate) traits: &'a [&'a str],
|
2020-04-10 03:07:09 -05:00
|
|
|
pub(crate) fields: &'a [Field<'a>],
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) enum Field<'a> {
|
|
|
|
Token(&'a str),
|
|
|
|
Node { name: &'a str, src: FieldSrc<'a> },
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
2020-04-10 02:14:14 -05:00
|
|
|
pub(crate) enum FieldSrc<'a> {
|
2020-01-03 13:37:02 -06:00
|
|
|
Shorthand,
|
2020-04-10 02:14:14 -05:00
|
|
|
Optional(&'a str),
|
|
|
|
Many(&'a str),
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) struct AstEnumSrc<'a> {
|
|
|
|
pub(crate) name: &'a str,
|
|
|
|
pub(crate) traits: &'a [&'a str],
|
|
|
|
pub(crate) variants: &'a [&'a str],
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! ast_nodes {
|
|
|
|
($(
|
|
|
|
struct $name:ident$(: $($trait:ident),*)? {
|
2020-04-10 03:07:09 -05:00
|
|
|
$($field_name:ident $(![$token:tt])? $(: $ty:tt)?),*$(,)?
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
)*) => {
|
|
|
|
[$(
|
|
|
|
AstNodeSrc {
|
|
|
|
name: stringify!($name),
|
|
|
|
traits: &[$($(stringify!($trait)),*)?],
|
2020-04-10 03:07:09 -05:00
|
|
|
fields: &[
|
|
|
|
$(field!($(T![$token])? $field_name $($ty)?)),*
|
|
|
|
],
|
2020-01-03 13:37:02 -06:00
|
|
|
|
|
|
|
}
|
|
|
|
),*]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-04-10 03:07:09 -05:00
|
|
|
macro_rules! field {
|
|
|
|
(T![$token:tt] T) => {
|
|
|
|
Field::Token(stringify!($token))
|
|
|
|
};
|
2020-01-03 13:37:02 -06:00
|
|
|
($field_name:ident) => {
|
2020-04-10 03:07:09 -05:00
|
|
|
Field::Node { name: stringify!($field_name), src: FieldSrc::Shorthand }
|
2020-01-03 13:37:02 -06:00
|
|
|
};
|
|
|
|
($field_name:ident [$ty:ident]) => {
|
2020-04-10 03:07:09 -05:00
|
|
|
Field::Node { name: stringify!($field_name), src: FieldSrc::Many(stringify!($ty)) }
|
2020-01-03 13:37:02 -06:00
|
|
|
};
|
|
|
|
($field_name:ident $ty:ident) => {
|
2020-04-10 03:07:09 -05:00
|
|
|
Field::Node { name: stringify!($field_name), src: FieldSrc::Optional(stringify!($ty)) }
|
2020-01-03 13:37:02 -06:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! ast_enums {
|
|
|
|
($(
|
|
|
|
enum $name:ident $(: $($trait:ident),*)? {
|
|
|
|
$($variant:ident),*$(,)?
|
|
|
|
}
|
|
|
|
)*) => {
|
|
|
|
[$(
|
|
|
|
AstEnumSrc {
|
|
|
|
name: stringify!($name),
|
|
|
|
traits: &[$($(stringify!($trait)),*)?],
|
|
|
|
variants: &[$(stringify!($variant)),*],
|
|
|
|
}
|
|
|
|
),*]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) const AST_SRC: AstSrc = AstSrc {
|
2020-04-10 08:53:09 -05:00
|
|
|
tokens: &["Whitespace", "Comment", "String", "RawString"],
|
2020-01-03 13:37:02 -06:00
|
|
|
nodes: &ast_nodes! {
|
2020-04-09 16:02:10 -05:00
|
|
|
struct SourceFile: ModuleItemOwner, AttrsOwner {
|
2020-01-03 13:37:02 -06:00
|
|
|
modules: [Module],
|
|
|
|
}
|
|
|
|
|
|
|
|
struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
|
2020-04-03 14:12:09 -05:00
|
|
|
Abi,
|
2020-04-10 03:07:09 -05:00
|
|
|
T![const],
|
|
|
|
T![default],
|
|
|
|
T![async],
|
|
|
|
T![unsafe],
|
|
|
|
T![fn],
|
2020-01-03 13:37:02 -06:00
|
|
|
ParamList,
|
|
|
|
RetType,
|
|
|
|
body: BlockExpr,
|
2020-04-10 03:11:05 -05:00
|
|
|
T![;]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
2020-04-10 03:18:43 -05:00
|
|
|
struct RetType { T![->], TypeRef }
|
2020-01-03 13:37:02 -06:00
|
|
|
|
|
|
|
struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![struct],
|
2020-04-03 14:12:09 -05:00
|
|
|
FieldDefList,
|
2020-04-10 03:11:05 -05:00
|
|
|
T![;]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![union],
|
2020-01-03 13:37:02 -06:00
|
|
|
RecordFieldDefList,
|
|
|
|
}
|
|
|
|
|
2020-04-10 03:27:23 -05:00
|
|
|
struct RecordFieldDefList { T!['{'], fields: [RecordFieldDef], T!['}'] }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { }
|
|
|
|
|
2020-04-10 03:29:59 -05:00
|
|
|
struct TupleFieldDefList { T!['('], fields: [TupleFieldDef], T![')'] }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct TupleFieldDef: VisibilityOwner, AttrsOwner {
|
|
|
|
TypeRef,
|
|
|
|
}
|
|
|
|
|
|
|
|
struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![enum],
|
2020-01-03 13:37:02 -06:00
|
|
|
variant_list: EnumVariantList,
|
|
|
|
}
|
|
|
|
struct EnumVariantList {
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['{'],
|
2020-01-03 13:37:02 -06:00
|
|
|
variants: [EnumVariant],
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['}']
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
2020-04-03 14:12:09 -05:00
|
|
|
struct EnumVariant: VisibilityOwner, NameOwner, DocCommentsOwner, AttrsOwner {
|
|
|
|
FieldDefList,
|
2020-04-10 03:35:39 -05:00
|
|
|
T![=],
|
2020-01-03 13:37:02 -06:00
|
|
|
Expr
|
|
|
|
}
|
|
|
|
|
|
|
|
struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![unsafe],
|
|
|
|
T![auto],
|
|
|
|
T![trait],
|
2020-01-03 13:37:02 -06:00
|
|
|
ItemList,
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![mod],
|
2020-01-03 13:37:02 -06:00
|
|
|
ItemList,
|
2020-04-10 03:11:05 -05:00
|
|
|
T![;]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
2020-04-09 16:02:10 -05:00
|
|
|
struct ItemList: ModuleItemOwner {
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['{'],
|
2020-01-03 13:37:02 -06:00
|
|
|
impl_items: [ImplItem],
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['}']
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![default],
|
|
|
|
T![const],
|
2020-04-10 03:35:39 -05:00
|
|
|
T![=],
|
2020-01-03 13:37:02 -06:00
|
|
|
body: Expr,
|
2020-04-10 03:11:05 -05:00
|
|
|
T![;]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![static],
|
|
|
|
T![mut],
|
2020-04-10 03:35:39 -05:00
|
|
|
T![=],
|
2020-01-03 13:37:02 -06:00
|
|
|
body: Expr,
|
2020-04-10 03:11:05 -05:00
|
|
|
T![;]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![default],
|
|
|
|
T![type],
|
2020-04-10 03:35:39 -05:00
|
|
|
T![=],
|
2020-01-03 13:37:02 -06:00
|
|
|
TypeRef,
|
2020-04-10 03:11:05 -05:00
|
|
|
T![;]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
2020-02-29 14:24:40 -06:00
|
|
|
struct ImplDef: TypeParamsOwner, AttrsOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![default],
|
|
|
|
T![const],
|
|
|
|
T![unsafe],
|
|
|
|
T![impl],
|
2020-04-10 03:35:39 -05:00
|
|
|
T![!],
|
2020-04-10 03:07:09 -05:00
|
|
|
T![for],
|
2020-01-03 13:37:02 -06:00
|
|
|
ItemList,
|
|
|
|
}
|
|
|
|
|
2020-04-10 03:29:59 -05:00
|
|
|
struct ParenType { T!['('], TypeRef, T![')'] }
|
|
|
|
struct TupleType { T!['('], fields: [TypeRef], T![')'] }
|
2020-04-10 03:35:39 -05:00
|
|
|
struct NeverType { T![!] }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct PathType { Path }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct PointerType { T![*], T![const], T![mut], TypeRef }
|
2020-04-10 03:29:59 -05:00
|
|
|
struct ArrayType { T!['['], TypeRef, T![;], Expr, T![']'] }
|
|
|
|
struct SliceType { T!['['], TypeRef, T![']'] }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct ReferenceType { T![&], T![lifetime], T![mut], TypeRef }
|
|
|
|
struct PlaceholderType { T![_] }
|
2020-04-10 03:07:09 -05:00
|
|
|
struct FnPointerType { Abi, T![unsafe], T![fn], ParamList, RetType }
|
|
|
|
struct ForType { T![for], TypeParamList, TypeRef }
|
|
|
|
struct ImplTraitType: TypeBoundsOwner { T![impl] }
|
|
|
|
struct DynTraitType: TypeBoundsOwner { T![dyn] }
|
2020-04-03 14:12:09 -05:00
|
|
|
|
2020-04-10 03:29:59 -05:00
|
|
|
struct TupleExpr: AttrsOwner { T!['('], exprs: [Expr], T![')'] }
|
|
|
|
struct ArrayExpr: AttrsOwner { T!['['], exprs: [Expr], T![;], T![']'] }
|
|
|
|
struct ParenExpr: AttrsOwner { T!['('], Expr, T![')'] }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct PathExpr { Path }
|
2020-04-03 14:12:09 -05:00
|
|
|
struct LambdaExpr: AttrsOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![static],
|
|
|
|
T![async],
|
|
|
|
T![move],
|
2020-01-03 13:37:02 -06:00
|
|
|
ParamList,
|
|
|
|
RetType,
|
|
|
|
body: Expr,
|
|
|
|
}
|
2020-04-10 03:07:09 -05:00
|
|
|
struct IfExpr: AttrsOwner { T![if], Condition }
|
|
|
|
struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
|
|
|
|
struct TryBlockExpr: AttrsOwner { T![try], body: BlockExpr }
|
2020-04-03 14:12:09 -05:00
|
|
|
struct ForExpr: AttrsOwner, LoopBodyOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![for],
|
2020-01-03 13:37:02 -06:00
|
|
|
Pat,
|
2020-04-10 03:07:09 -05:00
|
|
|
T![in],
|
2020-01-03 13:37:02 -06:00
|
|
|
iterable: Expr,
|
|
|
|
}
|
2020-04-10 03:07:09 -05:00
|
|
|
struct WhileExpr: AttrsOwner, LoopBodyOwner { T![while], Condition }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] }
|
|
|
|
struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr }
|
|
|
|
struct Label { T![lifetime] }
|
2020-04-30 14:36:31 -05:00
|
|
|
struct BlockExpr: AttrsOwner { Label, T![unsafe], T![async], Block }
|
2020-04-03 14:12:09 -05:00
|
|
|
struct ReturnExpr: AttrsOwner { Expr }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct CallExpr: ArgListOwner { Expr }
|
2020-04-03 14:12:09 -05:00
|
|
|
struct MethodCallExpr: AttrsOwner, ArgListOwner {
|
2020-04-10 04:49:13 -05:00
|
|
|
Expr, T![.], NameRef, TypeArgList,
|
2020-04-03 14:12:09 -05:00
|
|
|
}
|
2020-04-10 03:29:59 -05:00
|
|
|
struct IndexExpr: AttrsOwner { T!['['], T![']'] }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct FieldExpr: AttrsOwner { Expr, T![.], NameRef }
|
|
|
|
struct AwaitExpr: AttrsOwner { Expr, T![.], T![await] }
|
2020-04-10 03:07:09 -05:00
|
|
|
struct TryExpr: AttrsOwner { T![try], Expr }
|
|
|
|
struct CastExpr: AttrsOwner { Expr, T![as], TypeRef }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], Expr }
|
|
|
|
struct PrefixExpr: AttrsOwner { /*PrefixOp,*/ Expr }
|
2020-04-10 03:07:09 -05:00
|
|
|
struct BoxExpr: AttrsOwner { T![box], Expr }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct RangeExpr: AttrsOwner { /*RangeOp*/ }
|
2020-04-10 03:35:39 -05:00
|
|
|
struct BinExpr: AttrsOwner { /*BinOp*/ }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct Literal { /*LiteralToken*/ }
|
2020-04-03 14:12:09 -05:00
|
|
|
|
2020-04-10 03:07:09 -05:00
|
|
|
struct MatchExpr: AttrsOwner { T![match], Expr, MatchArmList }
|
2020-04-10 03:27:23 -05:00
|
|
|
struct MatchArmList: AttrsOwner { T!['{'], arms: [MatchArm], T!['}'] }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct MatchArm: AttrsOwner {
|
2020-02-09 12:57:01 -06:00
|
|
|
pat: Pat,
|
2020-01-03 13:37:02 -06:00
|
|
|
guard: MatchGuard,
|
2020-04-10 04:49:13 -05:00
|
|
|
T![=>],
|
2020-01-03 13:37:02 -06:00
|
|
|
Expr,
|
2020-02-11 15:33:11 -06:00
|
|
|
}
|
2020-04-10 03:07:09 -05:00
|
|
|
struct MatchGuard { T![if], Expr }
|
2020-01-03 13:37:02 -06:00
|
|
|
|
2020-04-03 14:12:09 -05:00
|
|
|
struct RecordLit { Path, RecordFieldList}
|
2020-01-03 13:37:02 -06:00
|
|
|
struct RecordFieldList {
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['{'],
|
2020-01-03 13:37:02 -06:00
|
|
|
fields: [RecordField],
|
2020-04-10 04:49:13 -05:00
|
|
|
T![..],
|
2020-01-03 13:37:02 -06:00
|
|
|
spread: Expr,
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['}']
|
2020-02-11 15:33:11 -06:00
|
|
|
}
|
2020-04-10 04:49:13 -05:00
|
|
|
struct RecordField: AttrsOwner { NameRef, T![:], Expr }
|
2020-01-03 13:37:02 -06:00
|
|
|
|
2020-02-09 12:57:01 -06:00
|
|
|
struct OrPat { pats: [Pat] }
|
2020-04-10 03:29:59 -05:00
|
|
|
struct ParenPat { T!['('], Pat, T![')'] }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct RefPat { T![&], T![mut], Pat }
|
2020-04-10 03:07:09 -05:00
|
|
|
struct BoxPat { T![box], Pat }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct BindPat: AttrsOwner, NameOwner { T![ref], T![mut], T![@], Pat }
|
|
|
|
struct PlaceholderPat { T![_] }
|
|
|
|
struct DotDotPat { T![..] }
|
2020-02-11 15:33:11 -06:00
|
|
|
struct PathPat { Path }
|
2020-04-10 03:29:59 -05:00
|
|
|
struct SlicePat { T!['['], args: [Pat], T![']'] }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct RangePat { /*RangeSeparator*/ }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct LiteralPat { Literal }
|
2020-04-03 08:38:42 -05:00
|
|
|
struct MacroPat { MacroCall }
|
2020-01-03 13:37:02 -06:00
|
|
|
|
|
|
|
struct RecordPat { RecordFieldPatList, Path }
|
|
|
|
struct RecordFieldPatList {
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['{'],
|
2020-04-03 14:12:09 -05:00
|
|
|
pats: [RecordInnerPat],
|
2020-01-03 13:37:02 -06:00
|
|
|
record_field_pats: [RecordFieldPat],
|
|
|
|
bind_pats: [BindPat],
|
2020-04-10 04:49:13 -05:00
|
|
|
T![..],
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['}']
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
2020-04-11 16:33:17 -05:00
|
|
|
struct RecordFieldPat: AttrsOwner { NameRef, T![:], Pat }
|
2020-01-03 13:37:02 -06:00
|
|
|
|
2020-04-10 03:29:59 -05:00
|
|
|
struct TupleStructPat { Path, T!['('], args: [Pat], T![')'] }
|
|
|
|
struct TuplePat { T!['('], args: [Pat], T![')'] }
|
2020-01-03 13:37:02 -06:00
|
|
|
|
2020-04-10 03:07:09 -05:00
|
|
|
struct Visibility { T![pub], T![super], T![self], T![crate] }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct Name { T![ident] }
|
|
|
|
struct NameRef { /*NameRefToken*/ }
|
2020-01-03 13:37:02 -06:00
|
|
|
|
|
|
|
struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner {
|
2020-04-10 03:35:39 -05:00
|
|
|
Path, T![!], TokenTree, T![;]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
2020-04-10 04:49:13 -05:00
|
|
|
struct Attr { T![#], T![!], T!['['], Path, T![=], input: AttrInput, T![']'] }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct TokenTree {}
|
|
|
|
struct TypeParamList {
|
2020-04-10 04:49:13 -05:00
|
|
|
T![<],
|
2020-04-03 14:12:09 -05:00
|
|
|
generic_params: [GenericParam],
|
2020-01-03 13:37:02 -06:00
|
|
|
type_params: [TypeParam],
|
|
|
|
lifetime_params: [LifetimeParam],
|
2020-04-03 14:12:09 -05:00
|
|
|
const_params: [ConstParam],
|
2020-04-10 04:49:13 -05:00
|
|
|
T![>]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner {
|
2020-04-10 03:35:39 -05:00
|
|
|
T![=],
|
2020-01-03 13:37:02 -06:00
|
|
|
default_type: TypeRef,
|
|
|
|
}
|
|
|
|
struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner {
|
2020-04-10 03:35:39 -05:00
|
|
|
T![=],
|
2020-01-03 13:37:02 -06:00
|
|
|
default_val: Expr,
|
|
|
|
}
|
2020-04-10 04:49:13 -05:00
|
|
|
struct LifetimeParam: AttrsOwner { T![lifetime] }
|
|
|
|
struct TypeBound { T![lifetime], /* Question, */ T![const], /* Question, */ TypeRef}
|
2020-01-03 13:37:02 -06:00
|
|
|
struct TypeBoundList { bounds: [TypeBound] }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct WherePred: TypeBoundsOwner { T![lifetime], TypeRef }
|
2020-04-10 03:07:09 -05:00
|
|
|
struct WhereClause { T![where], predicates: [WherePred] }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct Abi { /*String*/ }
|
2020-04-10 03:11:05 -05:00
|
|
|
struct ExprStmt: AttrsOwner { Expr, T![;] }
|
2020-04-03 14:12:09 -05:00
|
|
|
struct LetStmt: AttrsOwner, TypeAscriptionOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![let],
|
2020-01-03 13:37:02 -06:00
|
|
|
Pat,
|
2020-04-10 03:35:39 -05:00
|
|
|
T![=],
|
2020-01-03 13:37:02 -06:00
|
|
|
initializer: Expr,
|
2020-04-10 03:11:05 -05:00
|
|
|
T![;],
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
2020-04-10 03:35:39 -05:00
|
|
|
struct Condition { T![let], Pat, T![=], Expr }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct Block: AttrsOwner, ModuleItemOwner {
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['{'],
|
2020-01-03 13:37:02 -06:00
|
|
|
statements: [Stmt],
|
|
|
|
Expr,
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['}'],
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
struct ParamList {
|
2020-04-10 03:29:59 -05:00
|
|
|
T!['('],
|
2020-01-03 13:37:02 -06:00
|
|
|
SelfParam,
|
|
|
|
params: [Param],
|
2020-04-10 03:29:59 -05:00
|
|
|
T![')']
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
2020-04-10 10:47:49 -05:00
|
|
|
struct SelfParam: TypeAscriptionOwner, AttrsOwner { T![&], T![mut], T![lifetime], T![self] }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct Param: TypeAscriptionOwner, AttrsOwner {
|
|
|
|
Pat,
|
2020-04-10 04:49:13 -05:00
|
|
|
T![...]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
struct UseItem: AttrsOwner, VisibilityOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![use],
|
2020-01-03 13:37:02 -06:00
|
|
|
UseTree,
|
|
|
|
}
|
|
|
|
struct UseTree {
|
2020-04-10 04:49:13 -05:00
|
|
|
Path, T![*], UseTreeList, Alias
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
2020-04-10 03:07:09 -05:00
|
|
|
struct Alias: NameOwner { T![as] }
|
2020-04-10 03:27:23 -05:00
|
|
|
struct UseTreeList { T!['{'], use_trees: [UseTree], T!['}'] }
|
2020-01-03 13:37:02 -06:00
|
|
|
struct ExternCrateItem: AttrsOwner, VisibilityOwner {
|
2020-04-10 03:07:09 -05:00
|
|
|
T![extern], T![crate], NameRef, Alias,
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
struct ArgList {
|
2020-04-10 03:29:59 -05:00
|
|
|
T!['('],
|
2020-01-03 13:37:02 -06:00
|
|
|
args: [Expr],
|
2020-04-10 03:29:59 -05:00
|
|
|
T![')']
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
struct Path {
|
|
|
|
segment: PathSegment,
|
|
|
|
qualifier: Path,
|
|
|
|
}
|
|
|
|
struct PathSegment {
|
2020-04-27 12:02:47 -05:00
|
|
|
T![::], T![crate], T![<], NameRef, TypeArgList, ParamList, RetType, PathType, T![>]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
struct TypeArgList {
|
2020-04-10 04:49:13 -05:00
|
|
|
T![::],
|
|
|
|
T![<],
|
2020-04-03 14:12:09 -05:00
|
|
|
generic_args: [GenericArg],
|
2020-01-03 13:37:02 -06:00
|
|
|
type_args: [TypeArg],
|
|
|
|
lifetime_args: [LifetimeArg],
|
|
|
|
assoc_type_args: [AssocTypeArg],
|
2020-04-03 14:12:09 -05:00
|
|
|
const_args: [ConstArg],
|
2020-04-10 04:49:13 -05:00
|
|
|
T![>]
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
struct TypeArg { TypeRef }
|
2020-04-10 03:35:39 -05:00
|
|
|
struct AssocTypeArg : TypeBoundsOwner { NameRef, T![=], TypeRef }
|
2020-04-10 04:49:13 -05:00
|
|
|
struct LifetimeArg { T![lifetime] }
|
2020-04-10 03:35:39 -05:00
|
|
|
struct ConstArg { Literal, T![=], BlockExpr }
|
2020-01-03 13:37:02 -06:00
|
|
|
|
2020-04-09 16:02:10 -05:00
|
|
|
struct MacroItems: ModuleItemOwner{ }
|
2020-01-03 13:37:02 -06:00
|
|
|
|
|
|
|
struct MacroStmts {
|
|
|
|
statements: [Stmt],
|
|
|
|
Expr,
|
|
|
|
}
|
2020-04-03 14:12:09 -05:00
|
|
|
|
2020-04-09 16:02:10 -05:00
|
|
|
struct ExternItemList: ModuleItemOwner {
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['{'],
|
2020-04-03 14:12:09 -05:00
|
|
|
extern_items: [ExternItem],
|
2020-04-10 03:27:23 -05:00
|
|
|
T!['}']
|
2020-04-03 14:12:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
struct ExternBlock {
|
|
|
|
Abi,
|
|
|
|
ExternItemList
|
|
|
|
}
|
|
|
|
|
|
|
|
struct MetaItem {
|
2020-04-10 03:35:39 -05:00
|
|
|
Path, T![=], AttrInput, nested_meta_items: [MetaItem]
|
2020-04-03 14:12:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
struct MacroDef {
|
|
|
|
Name, TokenTree
|
|
|
|
}
|
2020-01-03 13:37:02 -06:00
|
|
|
},
|
|
|
|
enums: &ast_enums! {
|
|
|
|
enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner {
|
|
|
|
StructDef, EnumDef, UnionDef,
|
|
|
|
}
|
|
|
|
|
2020-04-03 14:12:09 -05:00
|
|
|
enum GenericParam {
|
|
|
|
LifetimeParam,
|
|
|
|
TypeParam,
|
|
|
|
ConstParam
|
|
|
|
}
|
|
|
|
|
|
|
|
enum GenericArg {
|
|
|
|
LifetimeArg,
|
|
|
|
TypeArg,
|
|
|
|
ConstArg,
|
|
|
|
AssocTypeArg
|
|
|
|
}
|
|
|
|
|
2020-01-03 13:37:02 -06:00
|
|
|
enum TypeRef {
|
|
|
|
ParenType,
|
|
|
|
TupleType,
|
|
|
|
NeverType,
|
|
|
|
PathType,
|
|
|
|
PointerType,
|
|
|
|
ArrayType,
|
|
|
|
SliceType,
|
|
|
|
ReferenceType,
|
|
|
|
PlaceholderType,
|
|
|
|
FnPointerType,
|
|
|
|
ForType,
|
|
|
|
ImplTraitType,
|
|
|
|
DynTraitType,
|
|
|
|
}
|
|
|
|
|
2020-04-03 14:12:09 -05:00
|
|
|
enum ModuleItem: NameOwner, AttrsOwner, VisibilityOwner {
|
2020-01-03 13:37:02 -06:00
|
|
|
StructDef,
|
|
|
|
UnionDef,
|
|
|
|
EnumDef,
|
|
|
|
FnDef,
|
|
|
|
TraitDef,
|
|
|
|
TypeAliasDef,
|
2020-02-29 14:24:40 -06:00
|
|
|
ImplDef,
|
2020-01-03 13:37:02 -06:00
|
|
|
UseItem,
|
|
|
|
ExternCrateItem,
|
|
|
|
ConstDef,
|
|
|
|
StaticDef,
|
|
|
|
Module,
|
2020-03-26 10:10:01 -05:00
|
|
|
MacroCall,
|
2020-04-03 14:12:09 -05:00
|
|
|
ExternBlock
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
2020-04-03 14:12:09 -05:00
|
|
|
/* impl blocks can also contain MacroCall */
|
|
|
|
enum ImplItem: NameOwner, AttrsOwner {
|
|
|
|
FnDef, TypeAliasDef, ConstDef
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
2020-04-03 14:12:09 -05:00
|
|
|
/* extern blocks can also contain MacroCall */
|
|
|
|
enum ExternItem: NameOwner, AttrsOwner, VisibilityOwner {
|
|
|
|
FnDef, StaticDef
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Expr: AttrsOwner {
|
2020-01-03 13:37:02 -06:00
|
|
|
TupleExpr,
|
|
|
|
ArrayExpr,
|
|
|
|
ParenExpr,
|
|
|
|
PathExpr,
|
|
|
|
LambdaExpr,
|
|
|
|
IfExpr,
|
|
|
|
LoopExpr,
|
|
|
|
ForExpr,
|
|
|
|
WhileExpr,
|
|
|
|
ContinueExpr,
|
|
|
|
BreakExpr,
|
|
|
|
Label,
|
|
|
|
BlockExpr,
|
|
|
|
ReturnExpr,
|
|
|
|
MatchExpr,
|
|
|
|
RecordLit,
|
|
|
|
CallExpr,
|
|
|
|
IndexExpr,
|
|
|
|
MethodCallExpr,
|
|
|
|
FieldExpr,
|
|
|
|
AwaitExpr,
|
|
|
|
TryExpr,
|
|
|
|
TryBlockExpr,
|
|
|
|
CastExpr,
|
|
|
|
RefExpr,
|
|
|
|
PrefixExpr,
|
|
|
|
RangeExpr,
|
|
|
|
BinExpr,
|
|
|
|
Literal,
|
|
|
|
MacroCall,
|
|
|
|
BoxExpr,
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Pat {
|
2020-02-09 12:57:01 -06:00
|
|
|
OrPat,
|
|
|
|
ParenPat,
|
2020-01-03 13:37:02 -06:00
|
|
|
RefPat,
|
|
|
|
BoxPat,
|
|
|
|
BindPat,
|
|
|
|
PlaceholderPat,
|
|
|
|
DotDotPat,
|
|
|
|
PathPat,
|
|
|
|
RecordPat,
|
|
|
|
TupleStructPat,
|
|
|
|
TuplePat,
|
|
|
|
SlicePat,
|
|
|
|
RangePat,
|
|
|
|
LiteralPat,
|
2020-04-03 08:38:42 -05:00
|
|
|
MacroPat,
|
2020-01-03 13:37:02 -06:00
|
|
|
}
|
|
|
|
|
2020-04-03 14:12:09 -05:00
|
|
|
enum RecordInnerPat {
|
|
|
|
RecordFieldPat,
|
|
|
|
BindPat
|
|
|
|
}
|
|
|
|
|
2020-01-03 13:37:02 -06:00
|
|
|
enum AttrInput { Literal, TokenTree }
|
2020-04-03 14:12:09 -05:00
|
|
|
enum Stmt {
|
|
|
|
LetStmt,
|
|
|
|
ExprStmt,
|
|
|
|
// macro calls are parsed as expression statements */
|
|
|
|
}
|
|
|
|
|
2020-04-09 10:58:15 -05:00
|
|
|
enum FieldDefList {
|
|
|
|
RecordFieldDefList,
|
|
|
|
TupleFieldDefList,
|
|
|
|
}
|
|
|
|
},
|
2020-01-03 13:37:02 -06:00
|
|
|
};
|