parser.rs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. use std::collections::HashSet;
  2. use serde_derive_internals::{
  3. ast::{Data, Field, Style, Variant},
  4. attr::TagType,
  5. };
  6. use crate::{
  7. attrs::TsifyFieldAttrs,
  8. container::Container,
  9. decl::{Decl, TsEnumDecl, TsInterfaceDecl, TsTypeAliasDecl},
  10. typescript::{TsType, TsTypeElement, TsTypeLit},
  11. };
  12. enum ParsedFields {
  13. Named(Vec<TsTypeElement>, Vec<TsType>),
  14. Unnamed(Vec<TsType>),
  15. Transparent(TsType),
  16. }
  17. impl From<ParsedFields> for TsType {
  18. fn from(fields: ParsedFields) -> Self {
  19. match fields {
  20. ParsedFields::Named(members, extends) => {
  21. let type_lit = TsType::from(TsTypeLit { members });
  22. if extends.is_empty() {
  23. type_lit
  24. } else {
  25. type_lit.and(TsType::Intersection(extends))
  26. }
  27. }
  28. ParsedFields::Unnamed(elems) => TsType::Tuple(elems),
  29. ParsedFields::Transparent(ty) => ty,
  30. }
  31. }
  32. }
  33. enum FieldsStyle {
  34. Named,
  35. Unnamed,
  36. }
  37. #[derive(Clone)]
  38. pub struct Parser<'a> {
  39. pub container: &'a Container<'a>,
  40. }
  41. impl<'a> Parser<'a> {
  42. pub fn new(container: &'a Container<'a>) -> Self {
  43. Self { container }
  44. }
  45. pub fn parse(&self) -> Decl {
  46. match self.container.serde_data() {
  47. Data::Struct(style, ref fields) => self.parse_struct(*style, fields),
  48. Data::Enum(ref variants) => self.parse_enum(variants),
  49. }
  50. }
  51. fn create_relevant_type_params(&self, type_ref_names: HashSet<&String>) -> Vec<String> {
  52. self.container
  53. .generics()
  54. .type_params()
  55. .into_iter()
  56. .map(|p| p.ident.to_string())
  57. .filter(|t| type_ref_names.contains(t))
  58. .collect()
  59. }
  60. fn create_type_alias_decl(&self, type_ann: TsType) -> Decl {
  61. Decl::TsTypeAlias(TsTypeAliasDecl {
  62. id: self.container.name(),
  63. export: true,
  64. type_params: self.create_relevant_type_params(type_ann.type_ref_names()),
  65. type_ann,
  66. })
  67. }
  68. fn create_decl(&self, members: Vec<TsTypeElement>, extends: Vec<TsType>) -> Decl {
  69. // An interface can only extend an identifier/qualified-name with optional type arguments.
  70. if extends.iter().all(|ty| ty.is_ref()) {
  71. let mut type_ref_names: HashSet<&String> = HashSet::new();
  72. members.iter().for_each(|member| {
  73. type_ref_names.extend(member.type_ann.type_ref_names());
  74. });
  75. extends.iter().for_each(|ty| {
  76. type_ref_names.extend(ty.type_ref_names());
  77. });
  78. let type_params = self.create_relevant_type_params(type_ref_names);
  79. Decl::TsInterface(TsInterfaceDecl {
  80. id: self.container.name(),
  81. type_params,
  82. extends,
  83. body: members,
  84. })
  85. } else {
  86. let extra = TsType::Intersection(
  87. extends
  88. .into_iter()
  89. .map(|ty| match ty {
  90. TsType::Option(ty) => TsType::Union(vec![*ty, TsType::empty_type_lit()]),
  91. _ => ty,
  92. })
  93. .collect(),
  94. );
  95. let type_ann = TsType::TypeLit(TsTypeLit { members }).and(extra);
  96. self.create_type_alias_decl(type_ann)
  97. }
  98. }
  99. fn parse_struct(&self, style: Style, fields: &[Field]) -> Decl {
  100. let parsed_fields = self.parse_fields(style, fields);
  101. let tag_type = self.container.serde_attrs().tag();
  102. match (tag_type, parsed_fields) {
  103. (TagType::Internal { tag }, ParsedFields::Named(members, extends)) => {
  104. let name = self.container.name();
  105. let tag_field = TsTypeElement {
  106. key: tag.clone(),
  107. type_ann: TsType::Lit(name),
  108. optional: false,
  109. };
  110. let mut vec = Vec::with_capacity(members.len() + 1);
  111. vec.push(tag_field);
  112. vec.extend(members);
  113. self.create_decl(vec, extends)
  114. }
  115. (_, ParsedFields::Named(members, extends)) => self.create_decl(members, extends),
  116. (_, parsed_fields) => self.create_type_alias_decl(parsed_fields.into()),
  117. }
  118. }
  119. fn parse_fields(&self, style: Style, fields: &[Field]) -> ParsedFields {
  120. let style = match style {
  121. Style::Struct => FieldsStyle::Named,
  122. Style::Newtype => return ParsedFields::Transparent(self.parse_field(&fields[0]).0),
  123. Style::Tuple => FieldsStyle::Unnamed,
  124. Style::Unit => return ParsedFields::Transparent(TsType::nullish()),
  125. };
  126. let fields = fields
  127. .iter()
  128. .filter(|field| {
  129. !field.attrs.skip_serializing()
  130. && !field.attrs.skip_deserializing()
  131. && !is_phantom(field.ty)
  132. })
  133. .collect::<Vec<_>>();
  134. if fields.len() == 1 && self.container.transparent() {
  135. return ParsedFields::Transparent(self.parse_field(fields[0]).0);
  136. }
  137. match style {
  138. FieldsStyle::Named => {
  139. let (members, flatten_fields) = self.parse_named_fields(fields);
  140. ParsedFields::Named(members, flatten_fields)
  141. }
  142. FieldsStyle::Unnamed => {
  143. let elems = fields
  144. .into_iter()
  145. .map(|field| self.parse_field(field).0)
  146. .collect();
  147. ParsedFields::Unnamed(elems)
  148. }
  149. }
  150. }
  151. fn parse_field(&self, field: &Field) -> (TsType, Option<TsifyFieldAttrs>) {
  152. let ts_attrs = match TsifyFieldAttrs::from_serde_field(field) {
  153. Ok(attrs) => attrs,
  154. Err(err) => {
  155. self.container.syn_error(err);
  156. return (TsType::NEVER, None);
  157. }
  158. };
  159. let type_ann = TsType::from(field.ty);
  160. if let Some(t) = &ts_attrs.type_override {
  161. let type_ref_names = type_ann.type_ref_names();
  162. let type_params = self.create_relevant_type_params(type_ref_names);
  163. (
  164. TsType::Override {
  165. type_override: t.clone(),
  166. type_params,
  167. },
  168. Some(ts_attrs),
  169. )
  170. } else {
  171. (type_ann, Some(ts_attrs))
  172. }
  173. }
  174. fn parse_named_fields(&self, fields: Vec<&Field>) -> (Vec<TsTypeElement>, Vec<TsType>) {
  175. let (flatten_fields, members): (Vec<_>, Vec<_>) =
  176. fields.into_iter().partition(|field| field.attrs.flatten());
  177. let members = members
  178. .into_iter()
  179. .map(|field| {
  180. let key = field.attrs.name().serialize_name();
  181. let (type_ann, field_attrs) = self.parse_field(field);
  182. let optional = field_attrs.map_or(false, |attrs| attrs.optional);
  183. let default_is_none = self.container.serde_attrs().default().is_none()
  184. && field.attrs.default().is_none();
  185. let type_ann = if optional {
  186. match type_ann {
  187. TsType::Option(t) => *t,
  188. _ => type_ann,
  189. }
  190. } else {
  191. type_ann
  192. };
  193. TsTypeElement {
  194. key,
  195. type_ann,
  196. optional: optional || !default_is_none,
  197. }
  198. })
  199. .collect();
  200. let flatten_fields = flatten_fields
  201. .into_iter()
  202. .map(|field| self.parse_field(field).0)
  203. .collect();
  204. (members, flatten_fields)
  205. }
  206. fn parse_enum(&self, variants: &[Variant]) -> Decl {
  207. let members = variants
  208. .iter()
  209. .filter(|v| !v.attrs.skip_serializing() && !v.attrs.skip_deserializing())
  210. .map(|variant| {
  211. let decl = self.create_type_alias_decl(self.parse_variant(variant));
  212. if let Decl::TsTypeAlias(mut type_alias) = decl {
  213. type_alias.id = variant.attrs.name().serialize_name();
  214. type_alias
  215. } else {
  216. panic!();
  217. }
  218. })
  219. .collect::<Vec<_>>();
  220. let type_ref_names = members
  221. .iter()
  222. .flat_map(|type_alias| type_alias.type_ann.type_ref_names())
  223. .collect::<HashSet<_>>();
  224. let relevant_type_params = self.create_relevant_type_params(type_ref_names);
  225. Decl::TsEnum(TsEnumDecl {
  226. id: self.container.name(),
  227. type_params: relevant_type_params,
  228. members,
  229. namespace: self.container.attrs.namespace,
  230. })
  231. }
  232. fn parse_variant(&self, variant: &Variant) -> TsType {
  233. let tag_type = self.container.serde_attrs().tag();
  234. let name = variant.attrs.name().serialize_name();
  235. let style = variant.style;
  236. let type_ann: TsType = self.parse_fields(style, &variant.fields).into();
  237. type_ann.with_tag_type(name, style, tag_type)
  238. }
  239. }
  240. fn is_phantom(ty: &syn::Type) -> bool {
  241. if let syn::Type::Path(syn::TypePath { path, .. }) = ty {
  242. path.segments
  243. .last()
  244. .map_or(false, |path| path.ident == "PhantomData")
  245. } else {
  246. false
  247. }
  248. }