ezno_parser/types/
type_declarations.rs1use crate::{
2 derive_ASTNode, errors::parse_lexing_error, tokens::token_as_identifier, ASTNode, ListItem,
3 ParseOptions, ParseResult, Span, TSXKeyword, TSXToken, TypeAnnotation,
4};
5use tokenizer_lib::TokenReader;
6
7#[derive(Debug, Clone, PartialEq)]
11#[apply(derive_ASTNode)]
12pub struct TypeParameter {
13 pub name: String,
14 pub default: Option<TypeAnnotation>,
15 pub extends: Option<TypeAnnotation>,
16 pub position: Span,
17 #[cfg(feature = "full-typescript")]
18 pub is_constant: bool,
19}
20
21impl ListItem for TypeParameter {
22 type LAST = ();
23}
24
25impl ASTNode for TypeParameter {
26 fn from_reader(
27 reader: &mut impl TokenReader<TSXToken, crate::TokenStart>,
28 state: &mut crate::ParsingState,
29 options: &ParseOptions,
30 ) -> ParseResult<Self> {
31 #[cfg(feature = "full-typescript")]
32 let is_constant = reader
33 .conditional_next(|t| matches!(t, TSXToken::Keyword(TSXKeyword::Const)))
34 .is_some();
35
36 let token = reader.next().ok_or_else(parse_lexing_error)?;
37 let (name, pos) = token_as_identifier(token, "type parameter name")?;
38
39 let extends = reader
40 .conditional_next(|t| matches!(t, TSXToken::Keyword(TSXKeyword::Extends)))
41 .is_some()
42 .then(|| TypeAnnotation::from_reader(reader, state, options))
43 .transpose()?;
44
45 let default = reader
46 .conditional_next(|t| matches!(t, TSXToken::Assign))
47 .is_some()
48 .then(|| TypeAnnotation::from_reader(reader, state, options))
49 .transpose()?;
50
51 let position = pos.get_start().union(
52 default
53 .as_ref()
54 .or(extends.as_ref())
55 .map_or(pos.get_end(), |ta| ta.get_position().get_end()),
56 );
57
58 Ok(Self {
59 name,
60 default,
61 extends,
62 position,
63 #[cfg(feature = "full-typescript")]
64 is_constant,
65 })
66 }
67
68 fn to_string_from_buffer<T: source_map::ToString>(
69 &self,
70 buf: &mut T,
71 options: &crate::ToStringOptions,
72 local: crate::LocalToStringInformation,
73 ) {
74 buf.push_str(&self.name);
75 if let Some(ref extends) = self.extends {
76 buf.push_str(" extends ");
77 extends.to_string_from_buffer(buf, options, local);
78 }
79 if let Some(ref default) = self.default {
80 buf.push_str(" = ");
81 default.to_string_from_buffer(buf, options, local);
82 }
83 }
84
85 fn get_position(&self) -> Span {
86 self.position
87 }
88}