1mod assignments;
7pub mod block;
8pub mod classes;
9pub mod declarations;
10pub mod definitions;
11pub mod expressions;
12mod extensions;
13pub mod functions;
14pub mod hoisting;
15pub mod interactive;
16pub mod interfaces;
17pub mod statements;
18pub mod type_annotations;
19pub mod variables;
20
21use block::synthesise_block;
22use parser::{
23 ASTNode, ExpressionPosition, ParseOptions, PropertyKey as ParserPropertyKey, StatementPosition,
24};
25use source_map::SourceId;
26
27use crate::{
28 context::{Environment, LocalInformation, Names, VariableRegisterArguments},
29 types::properties::PropertyKey,
30 CheckingData, Diagnostic, RootContext, TypeId, VariableId,
31};
32
33use self::{
34 declarations::synthesise_variable_declaration,
35 expressions::{synthesise_expression, synthesise_multiple_expression},
36 hoisting::hoist_variable_declaration,
37 type_annotations::synthesise_type_annotation,
38 variables::register_variable,
39};
40
41pub struct EznoParser;
42
43impl crate::ASTImplementation for EznoParser {
44 type ParseOptions = parser::ParseOptions;
45 type ParseError = (parser::ParseError, SourceId);
46 type ParserRequirements = ();
47
48 type Module<'_a> = parser::Module;
49 type OwnedModule = parser::Module;
50 type DefinitionFile<'_a> = parser::Module;
51
52 type TypeAnnotation<'_a> = parser::TypeAnnotation;
53 type TypeParameter<'_a> = parser::TypeParameter;
54 type Expression<'_a> = parser::Expression;
55 type Block<'_a> = parser::Block;
56 type MultipleExpression<'_a> = parser::expressions::MultipleExpression;
57 type ClassMethod<'_a> = parser::FunctionBase<parser::ast::ClassFunctionBase>;
58
59 type VariableField<'_a> = parser::VariableField;
60
61 type ForStatementInitiliser<'_a> = parser::statements::ForLoopStatementInitialiser;
62
63 fn module_from_string(
64 source_id: SourceId,
66 string: String,
67 options: Self::ParseOptions,
68 _parser_requirements: &mut Self::ParserRequirements,
69 ) -> Result<Self::Module<'static>, Self::ParseError> {
70 <parser::Module as parser::ASTNode>::from_string(string, options)
71 .map_err(|err| (err, source_id))
72 }
73
74 fn definition_module_from_string(
75 source_id: SourceId,
77 string: String,
78 _parser_requirements: &mut Self::ParserRequirements,
79 ) -> Result<Self::DefinitionFile<'static>, Self::ParseError> {
80 let options = ParseOptions { type_definition_module: true, ..Default::default() };
81
82 <parser::Module as parser::ASTNode>::from_string(string, options)
83 .map_err(|err| (err, source_id))
84 }
85
86 fn synthesise_module<T: crate::ReadFromFS>(
87 module: &Self::Module<'_>,
88 _source_id: SourceId,
89 module_environment: &mut Environment,
90 checking_data: &mut crate::CheckingData<T, Self>,
91 ) {
92 synthesise_block(&module.items, module_environment, checking_data);
93 }
94
95 fn synthesise_definition_module<T: crate::ReadFromFS>(
96 module: &Self::DefinitionFile<'_>,
97 source: SourceId,
98 root: &RootContext,
99 checking_data: &mut CheckingData<T, Self>,
100 ) -> (Names, LocalInformation) {
101 definitions::type_definition_file(module, source, checking_data, root)
102 }
103
104 fn synthesise_expression<U: crate::ReadFromFS>(
105 expression: &Self::Expression<'_>,
106 expecting: TypeId,
107 environment: &mut Environment,
108 checking_data: &mut CheckingData<U, Self>,
109 ) -> TypeId {
110 synthesise_expression(expression, environment, checking_data, expecting)
111 }
112
113 fn expression_position<'_a>(expression: &'_a Self::Expression<'_a>) -> source_map::Span {
114 ASTNode::get_position(expression)
115 }
116
117 fn multiple_expression_position<'_a>(
118 expression: &'_a Self::MultipleExpression<'_a>,
119 ) -> source_map::Span {
120 ASTNode::get_position(expression)
121 }
122
123 fn type_parameter_name<'_a>(parameter: &'_a Self::TypeParameter<'_a>) -> &'_a str {
124 ¶meter.name
125 }
126
127 fn synthesise_type_parameter_extends<T: crate::ReadFromFS>(
128 parameter: &Self::TypeParameter<'_>,
129 environment: &mut Environment,
130 checking_data: &mut crate::CheckingData<T, Self>,
131 ) -> TypeId {
132 if let Some(ref extends) = parameter.extends {
133 synthesise_type_annotation(extends, environment, checking_data)
134 } else {
135 TypeId::ANY_TYPE
136 }
137 }
138
139 fn type_annotation_position<'_a>(
140 annotation: &'_a Self::TypeAnnotation<'_a>,
141 ) -> source_map::Span {
142 ASTNode::get_position(annotation)
143 }
144
145 fn synthesise_type_annotation<T: crate::ReadFromFS>(
146 annotation: &Self::TypeAnnotation<'_>,
147 environment: &mut Environment,
148 checking_data: &mut crate::CheckingData<T, Self>,
149 ) -> TypeId {
150 synthesise_type_annotation(annotation, environment, checking_data)
151 }
152
153 fn parse_options(
154 is_js: bool,
155 extra_syntax: bool,
156 parse_comments: bool,
157 lsp_mode: bool,
158 ) -> Self::ParseOptions {
159 parser::ParseOptions {
160 comments: if parse_comments {
161 parser::Comments::JustDocumentation
162 } else {
163 parser::Comments::None
164 },
165 type_annotations: !is_js,
166 partial_syntax: lsp_mode,
167 retain_blank_lines: lsp_mode,
169 is_expressions: extra_syntax,
170 ..Default::default()
171 }
172 }
173
174 fn owned_module_from_module(m: Self::Module<'static>) -> Self::OwnedModule {
175 m
176 }
177
178 fn synthesise_multiple_expression<'_a, T: crate::ReadFromFS>(
179 expression: &'_a Self::MultipleExpression<'_a>,
180 expected_type: TypeId,
181 environment: &mut Environment,
182 checking_data: &mut crate::CheckingData<T, Self>,
183 ) -> TypeId {
184 synthesise_multiple_expression(expression, environment, checking_data, expected_type)
185 }
186
187 fn synthesise_for_loop_initialiser<'_a, T: crate::ReadFromFS>(
188 for_loop_initialiser: &'_a Self::ForStatementInitiliser<'_a>,
189 environment: &mut Environment,
190 checking_data: &mut crate::CheckingData<T, Self>,
191 ) {
192 match for_loop_initialiser {
193 parser::statements::ForLoopStatementInitialiser::VariableDeclaration(declaration) => {
194 hoist_variable_declaration(declaration, environment, checking_data);
196 synthesise_variable_declaration(
197 declaration,
198 environment,
199 checking_data,
200 false,
201 checking_data.options.infer_sensible_constraints_in_for_loops,
203 );
204 }
205 parser::statements::ForLoopStatementInitialiser::VarStatement(stmt) => {
206 checking_data.raise_unimplemented_error(
207 "var in for statement initiliser",
208 stmt.get_position().with_source(environment.get_source()),
209 );
210 }
211 parser::statements::ForLoopStatementInitialiser::Expression(expr) => {
212 checking_data.raise_unimplemented_error(
213 "expression as for statement initiliser",
214 expr.get_position().with_source(environment.get_source()),
215 );
216 }
217 }
218 }
219
220 fn declare_and_assign_to_fields<'a, T: crate::ReadFromFS>(
221 field: &'a Self::VariableField<'a>,
222 environment: &mut Environment,
223 checking_data: &mut crate::CheckingData<T, Self>,
224 arguments: VariableRegisterArguments,
225 ) {
226 register_variable(field, environment, checking_data, arguments);
227 }
228
229 fn parameter_constrained<'a>(parameter: &'a Self::TypeParameter<'a>) -> bool {
230 parameter.extends.is_some()
231 }
232
233 fn synthesise_block<'a, T: crate::ReadFromFS>(
234 block: &'a Self::Block<'a>,
235 environment: &mut Environment,
236 checking_data: &mut crate::CheckingData<T, Self>,
237 ) {
238 synthesise_block(&block.0, environment, checking_data);
239 }
240}
241
242pub(super) fn parser_property_key_to_checker_property_key<
244 P: parser::property_key::PropertyKeyKind,
245 T: crate::ReadFromFS,
246>(
247 property_key: &ParserPropertyKey<P>,
248 environment: &mut Environment,
249 checking_data: &mut CheckingData<T, EznoParser>,
250 perform_side_effect_computed: bool,
251) -> PropertyKey<'static> {
252 match property_key {
253 ParserPropertyKey::StringLiteral(value, ..) | ParserPropertyKey::Identifier(value, ..) => {
254 PropertyKey::String(std::borrow::Cow::Owned(value.clone()))
255 }
256 ParserPropertyKey::NumberLiteral(number, pos) => {
257 let result = f64::try_from(number.clone());
258 if let Ok(v) = result {
259 #[allow(clippy::float_cmp)]
261 if v.floor() == v {
262 PropertyKey::from_usize(v as usize)
263 } else {
264 PropertyKey::String(std::borrow::Cow::Owned(v.to_string()))
266 }
267 } else {
268 checking_data.raise_unimplemented_error(
269 "big int as property key",
270 pos.with_source(environment.get_source()),
271 );
272 PropertyKey::Type(TypeId::UNIMPLEMENTED_ERROR_TYPE)
273 }
274 }
275 ParserPropertyKey::Computed(expression, _) => {
276 if perform_side_effect_computed {
277 let key_type =
278 synthesise_expression(expression, environment, checking_data, TypeId::ANY_TYPE);
279 PropertyKey::from_type(key_type, &checking_data.types)
280 } else {
281 PropertyKey::Type(TypeId::ANY_TYPE)
282 }
283 }
284 }
285}
286
287impl From<(parser::ParseError, SourceId)> for Diagnostic {
288 fn from(parse_error: (parser::ParseError, SourceId)) -> Self {
289 Diagnostic::Position {
290 reason: parse_error.0.reason,
291 position: parse_error.0.position.with_source(parse_error.1),
292 kind: crate::diagnostics::DiagnosticKind::Error,
293 }
294 }
295}
296
297impl crate::GenericTypeParameter for parser::TypeParameter {
298 fn get_name(&self) -> &str {
299 &self.name
300 }
301}
302
303pub trait StatementOrExpressionVariable {
304 fn get_variable_id(&self, under: SourceId) -> Option<VariableId>;
305}
306
307impl StatementOrExpressionVariable for StatementPosition {
308 fn get_variable_id(&self, under: SourceId) -> Option<VariableId> {
309 match self.identifier {
310 parser::VariableIdentifier::Standard(_, pos) => Some(VariableId(under, pos.start)),
311 parser::VariableIdentifier::Marker(_, _) => None,
312 }
313 }
314}
315
316impl StatementOrExpressionVariable for ExpressionPosition {
317 fn get_variable_id(&self, _under: SourceId) -> Option<VariableId> {
318 None
319 }
320}