ezno_parser/types/
type_declarations.rs

1use 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/// Represents a generic parameter. Can have default or constraint to extend a type or a key of a type
8///
9/// TODO is default and extends mut ex
10#[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}