fusee-framework 2.7.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +56 -2
  2. package/bin/create-fusee-linux +0 -0
  3. package/bin/create-fusee-mac-arm64 +0 -0
  4. package/bin/create-fusee-mac-intel +0 -0
  5. package/bin/create-fusee-win.exe +0 -0
  6. package/framework/auto-import-preset.js +20 -12
  7. package/framework/auto-imports.d.ts +68 -39
  8. package/framework/core/compiler.js +310 -310
  9. package/framework/core/component-core.js +445 -0
  10. package/framework/core/component.js +11 -440
  11. package/framework/core/composable.js +29 -29
  12. package/framework/core/h.js +588 -557
  13. package/framework/core/jsx-helpers.js +11 -2
  14. package/framework/core/jsx-runtime.js +73 -73
  15. package/framework/core/rust-compiler/pkg/fusee_compiler_bg.wasm +0 -0
  16. package/framework/core/store.js +333 -333
  17. package/framework/globals.js +42 -0
  18. package/framework/index.js +22 -55
  19. package/framework/router/file-router.js +184 -184
  20. package/framework/server/actions.js +183 -183
  21. package/framework/server/generate-manifest.js +3 -3
  22. package/framework/types/component.d.ts +97 -86
  23. package/framework/types/index.d.ts +118 -117
  24. package/package.json +83 -80
  25. package/framework/core/rust-compiler/Cargo.toml +0 -31
  26. package/framework/core/rust-compiler/README.md +0 -69
  27. package/framework/core/rust-compiler/pkg/README.md +0 -69
  28. package/framework/core/rust-compiler/pkg/fusee_compiler.d.ts +0 -6
  29. package/framework/core/rust-compiler/pkg/fusee_compiler.js +0 -9
  30. package/framework/core/rust-compiler/pkg/fusee_compiler_bg.js +0 -137
  31. package/framework/core/rust-compiler/pkg/fusee_compiler_bg.wasm.d.ts +0 -11
  32. package/framework/core/rust-compiler/pkg/package.json +0 -18
  33. package/framework/core/rust-compiler/src/ast.rs +0 -274
  34. package/framework/core/rust-compiler/src/errors.rs +0 -204
  35. package/framework/core/rust-compiler/src/generator.rs +0 -583
  36. package/framework/core/rust-compiler/src/lexer.rs +0 -414
  37. package/framework/core/rust-compiler/src/lib.rs +0 -87
  38. package/framework/core/rust-compiler/src/main_compiler.rs +0 -165
  39. package/framework/core/rust-compiler/src/parser.rs +0 -516
  40. package/framework/core/rust-compiler/src/ssr_generator.rs +0 -688
  41. package/framework/core/rust-compiler/src/transformer.rs +0 -562
  42. package/framework/core/rust-compiler/src/utils.rs +0 -10
  43. package/framework/engine-go/actions.go +0 -112
  44. package/framework/engine-go/cmd/server/main.go +0 -233
  45. package/framework/engine-go/comet/comet.go +0 -41
  46. package/framework/engine-go/comet/fragment.go +0 -51
  47. package/framework/engine-go/dispatcher.go +0 -120
  48. package/framework/engine-go/elements.go +0 -248
  49. package/framework/engine-go/evalexpr/evalexpr.go +0 -733
  50. package/framework/engine-go/go.mod +0 -3
  51. package/framework/engine-go/hydration.go +0 -43
  52. package/framework/engine-go/load-helpers.go +0 -29
  53. package/framework/engine-go/manifest.go +0 -41
  54. package/framework/engine-go/reactive.go +0 -123
  55. package/framework/engine-go/render.go +0 -635
  56. package/framework/engine-go/reqcontext.go +0 -48
  57. package/framework/engine-go/router.go +0 -85
  58. package/framework/engine-go/rustast/rustast.go +0 -317
  59. package/framework/engine-go/ssr.go +0 -103
  60. package/framework/engine-go/static-assets.go +0 -139
  61. package/framework/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
@@ -1,414 +0,0 @@
1
- use crate::args;
2
- use crate::ast::{Loc, Pos};
3
- use crate::errors::{CompileError, ErrorCode};
4
- use serde::Serialize;
5
-
6
- #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
7
- pub enum TokenType {
8
- TagOpen,
9
- TagOpenClose,
10
- TagClose,
11
- TagSelfClose,
12
- Comment,
13
- AttrName,
14
- AttrEquals,
15
- AttrValue,
16
- Text,
17
- MustacheOpen,
18
- MustacheExpr,
19
- MustacheClose,
20
- Eof,
21
- }
22
-
23
- #[derive(Debug, Clone, Serialize)]
24
- pub struct Token {
25
- pub ttype: TokenType,
26
- pub value: String,
27
- pub loc: Loc,
28
- }
29
-
30
- #[derive(PartialEq, Eq, Clone, Copy)]
31
- enum Mode {
32
- Text,
33
- Tag,
34
- }
35
-
36
- pub fn tokenize(source: &str) -> Result<Vec<Token>, CompileError> {
37
- let mut lexer = Lexer::new(source);
38
- lexer.tokenize()
39
- }
40
-
41
- struct Lexer {
42
- chars: Vec<char>,
43
- source: String,
44
- tokens: Vec<Token>,
45
- pos: usize,
46
- line: usize,
47
- col: usize,
48
- mode: Mode,
49
- }
50
-
51
- impl Lexer {
52
- fn new(source: &str) -> Self {
53
- Lexer {
54
- chars: source.chars().collect(),
55
- source: source.to_string(),
56
- tokens: Vec::new(),
57
- pos: 0,
58
- line: 1,
59
- col: 1,
60
- mode: Mode::Text,
61
- }
62
- }
63
-
64
- fn tokenize(&mut self) -> Result<Vec<Token>, CompileError> {
65
- while !self.eof() {
66
- match self.mode {
67
- Mode::Text => self.read_text()?,
68
- Mode::Tag => self.read_in_tag()?,
69
- }
70
- }
71
- let start = self.start_pos();
72
- self.push(TokenType::Eof, String::new(), start);
73
- Ok(std::mem::take(&mut self.tokens))
74
- }
75
-
76
- fn read_text(&mut self) -> Result<(), CompileError> {
77
- if self.looking_at("<!--") {
78
- return self.read_comment();
79
- }
80
- if self.looking_at("</") {
81
- return self.read_closing_tag();
82
- }
83
- if self.peek() == Some('<') && self.is_tag_name_start(self.peek_at(1)) {
84
- return self.read_open_tag();
85
- }
86
- if self.looking_at("{{") {
87
- return self.read_mustache();
88
- }
89
-
90
- let start = self.start_pos();
91
- let mut text = String::new();
92
- while !self.eof() {
93
- if self.peek() == Some('<') || self.looking_at("{{") {
94
- break;
95
- }
96
- text.push(self.advance());
97
- }
98
- if !text.is_empty() {
99
- self.push(TokenType::Text, text, start);
100
- }
101
- Ok(())
102
- }
103
-
104
- fn read_open_tag(&mut self) -> Result<(), CompileError> {
105
- let start = self.start_pos();
106
- self.consume("<")?;
107
- let name = self.read_tag_name();
108
- self.push(TokenType::TagOpen, name, start);
109
- self.mode = Mode::Tag;
110
- Ok(())
111
- }
112
-
113
- fn read_closing_tag(&mut self) -> Result<(), CompileError> {
114
- let start = self.start_pos();
115
- self.consume("</")?;
116
- let name = self.read_tag_name();
117
- self.push(TokenType::TagOpenClose, name, start);
118
- self.skip_whitespace();
119
- if !self.eof() && self.peek() == Some('>') {
120
- let close_start = self.start_pos();
121
- self.consume(">")?;
122
- self.push(TokenType::TagClose, ">".into(), close_start);
123
- }
124
- Ok(())
125
- }
126
-
127
- fn read_comment(&mut self) -> Result<(), CompileError> {
128
- let start = self.start_pos();
129
- self.consume("<!--")?;
130
- let mut content = String::new();
131
- while !self.eof() && !self.looking_at("-->") {
132
- content.push(self.advance());
133
- }
134
- if self.eof() {
135
- return Err(CompileError::new(
136
- ErrorCode::MalformedComment,
137
- Loc::new(start, self.start_pos()),
138
- &self.source,
139
- args!(),
140
- ));
141
- }
142
- self.consume("-->")?;
143
- self.push(TokenType::Comment, content.trim().to_string(), start);
144
- Ok(())
145
- }
146
-
147
- fn read_mustache(&mut self) -> Result<(), CompileError> {
148
- let open_start = self.start_pos();
149
- self.consume("{{")?;
150
- self.push(TokenType::MustacheOpen, "{{".into(), open_start);
151
-
152
- let expr_start = self.start_pos();
153
- let mut expr = String::new();
154
- let mut depth = 0i32;
155
- let mut in_str = false;
156
- let mut str_char: Option<char> = None;
157
-
158
- while !self.eof() {
159
- let ch = self.peek().unwrap();
160
-
161
- if in_str {
162
- if ch == '\\' {
163
- expr.push(self.advance());
164
- if !self.eof() {
165
- expr.push(self.advance());
166
- }
167
- continue;
168
- }
169
- if Some(ch) == str_char {
170
- in_str = false;
171
- }
172
- expr.push(self.advance());
173
- continue;
174
- }
175
-
176
- if ch == '"' || ch == '\'' || ch == '`' {
177
- in_str = true;
178
- str_char = Some(ch);
179
- expr.push(self.advance());
180
- continue;
181
- }
182
- if ch == '{' {
183
- depth += 1;
184
- expr.push(self.advance());
185
- continue;
186
- }
187
- if ch == '}' {
188
- if depth > 0 {
189
- depth -= 1;
190
- expr.push(self.advance());
191
- continue;
192
- }
193
- if self.peek_at(1) == Some('}') {
194
- self.push(TokenType::MustacheExpr, expr.trim().to_string(), expr_start);
195
- let close_start = self.start_pos();
196
- self.consume("}}")?;
197
- self.push(TokenType::MustacheClose, "}}".into(), close_start);
198
- return Ok(());
199
- }
200
- }
201
-
202
- expr.push(self.advance());
203
- }
204
-
205
- Err(CompileError::new(
206
- ErrorCode::UnterminatedMustache,
207
- Loc::new(open_start, self.start_pos()),
208
- &self.source,
209
- args!(expr),
210
- ))
211
- }
212
-
213
- fn read_in_tag(&mut self) -> Result<(), CompileError> {
214
- self.skip_whitespace();
215
- if self.eof() {
216
- return Ok(());
217
- }
218
-
219
- if self.matches("/>") {
220
- self.push(TokenType::TagSelfClose, "/>".into(), self.start_pos());
221
- self.mode = Mode::Text;
222
- return Ok(());
223
- }
224
-
225
- if self.peek() == Some('>') {
226
- self.consume(">")?;
227
- self.push(TokenType::TagClose, ">".into(), self.start_pos());
228
- self.mode = Mode::Text;
229
- return Ok(());
230
- }
231
-
232
- let start = self.start_pos();
233
- let name = self.read_attr_name();
234
- let name = match name {
235
- Some(n) => n,
236
- None => return Ok(()),
237
- };
238
-
239
- self.push(TokenType::AttrName, name, start);
240
- self.skip_whitespace();
241
-
242
- if self.peek() == Some('=') {
243
- self.consume("=")?;
244
- self.push(TokenType::AttrEquals, "=".into(), self.start_pos());
245
- self.skip_whitespace();
246
- self.read_attr_value();
247
- }
248
-
249
- Ok(())
250
- }
251
-
252
- fn read_attr_name(&mut self) -> Option<String> {
253
- let mut name = String::new();
254
-
255
- if self.peek() == Some('@') || self.peek() == Some(':') {
256
- name.push(self.advance());
257
- }
258
-
259
- while !self.eof() {
260
- let ch = self.peek().unwrap();
261
- if ch.is_ascii_alphanumeric() || "-_.:".contains(ch) {
262
- name.push(self.advance());
263
- } else {
264
- break;
265
- }
266
- }
267
-
268
- if name.is_empty() {
269
- None
270
- } else {
271
- Some(name)
272
- }
273
- }
274
-
275
- fn read_attr_value(&mut self) {
276
- if self.eof() {
277
- return;
278
- }
279
- let quote = self.peek().unwrap();
280
- if quote != '"' && quote != '\'' {
281
- let start = self.start_pos();
282
- let mut val = String::new();
283
- while !self.eof() {
284
- let ch = self.peek().unwrap();
285
- if ch.is_whitespace() || ch == '>' {
286
- break;
287
- }
288
- val.push(self.advance());
289
- }
290
- self.push(TokenType::AttrValue, val, start);
291
- return;
292
- }
293
-
294
- self.advance();
295
- let start = self.start_pos();
296
- let mut val = String::new();
297
-
298
- while !self.eof() {
299
- let ch = self.peek().unwrap();
300
- if ch == quote {
301
- self.advance();
302
- break;
303
- }
304
- if ch == '\\' {
305
- self.advance();
306
- if !self.eof() {
307
- val.push(self.advance());
308
- }
309
- continue;
310
- }
311
- val.push(self.advance());
312
- }
313
-
314
- self.push(TokenType::AttrValue, val, start);
315
- }
316
-
317
- fn read_tag_name(&mut self) -> String {
318
- let mut name = String::new();
319
- while !self.eof() {
320
- let ch = self.peek().unwrap();
321
- if ch.is_ascii_alphanumeric() || "-_.".contains(ch) {
322
- name.push(self.advance());
323
- } else {
324
- break;
325
- }
326
- }
327
- name
328
- }
329
-
330
- fn is_tag_name_start(&self, ch: Option<char>) -> bool {
331
- matches!(ch, Some(c) if c.is_ascii_alphabetic() || c == '_')
332
- }
333
-
334
-
335
- fn eof(&self) -> bool {
336
- self.pos >= self.chars.len()
337
- }
338
-
339
- fn peek(&self) -> Option<char> {
340
-
341
- self.chars.get(self.pos).copied()
342
- }
343
-
344
- fn peek_at(&self, n: usize) -> Option<char> {
345
-
346
- self.chars.get(self.pos + n).copied()
347
- }
348
-
349
- fn looking_at(&self, s: &str) -> bool {
350
- let s_chars: Vec<char> = s.chars().collect();
351
- if self.pos + s_chars.len() > self.chars.len() {
352
- return false;
353
- }
354
- self.chars[self.pos..self.pos + s_chars.len()] == s_chars[..]
355
- }
356
-
357
- fn matches(&mut self, s: &str) -> bool {
358
- if self.looking_at(s) {
359
- for _ in s.chars() {
360
- self.advance();
361
- }
362
- true
363
- } else {
364
- false
365
- }
366
- }
367
-
368
- fn consume(&mut self, expected: &str) -> Result<(), CompileError> {
369
- for ch in expected.chars() {
370
- if self.chars.get(self.pos) != Some(&ch) {
371
- let found = self
372
- .chars
373
- .get(self.pos)
374
- .map(|c| c.to_string())
375
- .unwrap_or_default();
376
- return Err(CompileError::new(
377
- ErrorCode::UnexpectedChar,
378
- Loc::new(self.start_pos(), self.start_pos()),
379
- &self.source,
380
- args!(found),
381
- ));
382
- }
383
- self.advance();
384
- }
385
- Ok(())
386
- }
387
-
388
- fn advance(&mut self) -> char {
389
- let ch = self.chars[self.pos];
390
- self.pos += 1;
391
- if ch == '\n' {
392
- self.line += 1;
393
- self.col = 1;
394
- } else {
395
- self.col += 1;
396
- }
397
- ch
398
- }
399
-
400
- fn skip_whitespace(&mut self) {
401
- while !self.eof() && self.peek().map(|c| c.is_whitespace()).unwrap_or(false) {
402
- self.advance();
403
- }
404
- }
405
-
406
- fn start_pos(&self) -> Pos {
407
- Pos::new(self.line, self.col, self.pos)
408
- }
409
-
410
- fn push(&mut self, ttype: TokenType, value: String, start: Pos) {
411
- let loc = Loc::new(start, self.start_pos());
412
- self.tokens.push(Token { ttype, value, loc });
413
- }
414
- }
@@ -1,87 +0,0 @@
1
- #![allow(dead_code)]
2
-
3
- pub mod utils;
4
- pub mod errors;
5
- pub mod ast;
6
- pub mod generator;
7
- pub mod ssr_generator;
8
- pub mod lexer;
9
- pub mod main_compiler;
10
- pub mod parser;
11
- pub mod transformer;
12
-
13
- use serde::Deserialize;
14
- use wasm_bindgen::prelude::*;
15
- use crate::main_compiler::{CompileOptions, CompileTarget};
16
-
17
- // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
18
- // allocator.
19
- #[cfg(feature = "wee_alloc")]
20
- #[global_allocator]
21
- static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
22
-
23
- #[wasm_bindgen]
24
- extern {
25
- fn alert(s: &str);
26
- }
27
-
28
- #[derive(Deserialize)]
29
- #[serde(rename_all = "camelCase")]
30
- struct RustCompileOptions {
31
- #[serde(default)]
32
- filename: Option<String>,
33
- #[serde(default)]
34
- components: Option<Vec<String>>,
35
- #[serde(default)]
36
- scope: Option<Vec<String>>,
37
- #[serde(default)]
38
- runtime_path: Option<String>,
39
- #[serde(default)]
40
- ssr_runtime_path: Option<String>,
41
- #[serde(default)]
42
- throw_on_warning: Option<bool>,
43
- #[serde(default)]
44
- target: Option<String>,
45
- }
46
-
47
- #[wasm_bindgen]
48
- pub fn compile(source: &str, options_json: &str) -> Result<String, JsValue> {
49
- let opts: RustCompileOptions = serde_json::from_str(options_json)
50
- .map_err(|e| JsValue::from_str(&format!("Invalid compiler options: {e}")))?;
51
- let filename = opts.filename.clone().unwrap_or_else(|| "<template>".to_string());
52
-
53
- let target = match opts.target.as_deref() {
54
- Some("ssr") => CompileTarget::SSR,
55
- Some("both") => CompileTarget::Both,
56
- _ => CompileTarget::Client,
57
- };
58
-
59
- let compile_opts = CompileOptions {
60
- filename: filename.clone(),
61
- components: opts.components.unwrap_or_default().into_iter().collect(),
62
- scope: opts.scope.unwrap_or_default().into_iter().collect(),
63
- runtime_path: opts.runtime_path,
64
- ssr_runtime_path: opts.ssr_runtime_path,
65
- throw_on_warning: opts.throw_on_warning.unwrap_or(false),
66
- target,
67
- };
68
-
69
- match main_compiler::compile(source, compile_opts) {
70
- Ok(r) => {
71
- let out = serde_json::json!({
72
- "code": r.code,
73
- "ssrCode": r.ssr_code,
74
- "ast": r.ast,
75
- "tokens": r.tokens,
76
- "warnings": r.warnings,
77
- });
78
- serde_json::to_string(&out).map_err(|e| JsValue::from_str(&e.to_string()))
79
- }
80
- Err(e) => Err(JsValue::from_str(&e.format(&filename))),
81
- }
82
- }
83
-
84
- #[wasm_bindgen]
85
- pub fn greet() {
86
- alert("Hello, rust-compiler!");
87
- }
@@ -1,165 +0,0 @@
1
- use crate::ast::Node;
2
- use crate::errors::{CompileError, CompileWarning};
3
- use crate::generator::{generate, GenerateOptions};
4
- use crate::lexer::{tokenize, Token};
5
- use crate::parser::parse;
6
- use crate::ssr_generator::{generate_ssr, SSRGenerateOptions};
7
- use crate::transformer::{transform, TransformOptions};
8
- use std::collections::HashSet;
9
-
10
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
11
- pub enum CompileTarget {
12
- Client,
13
- SSR,
14
- Both,
15
- }
16
-
17
- impl Default for CompileTarget {
18
- fn default() -> Self {
19
- CompileTarget::Client
20
- }
21
- }
22
-
23
- pub struct CompileOptions {
24
- pub filename: String,
25
- pub components: HashSet<String>,
26
- pub scope: HashSet<String>,
27
- pub runtime_path: Option<String>,
28
- pub ssr_runtime_path: Option<String>,
29
- pub throw_on_warning: bool,
30
- pub target: CompileTarget,
31
- }
32
-
33
- impl Default for CompileOptions {
34
- fn default() -> Self {
35
- CompileOptions {
36
- filename: "<template>".to_string(),
37
- components: HashSet::new(),
38
- scope: HashSet::new(),
39
- runtime_path: None,
40
- ssr_runtime_path: None,
41
- throw_on_warning: false,
42
- target: CompileTarget::Client,
43
- }
44
- }
45
- }
46
-
47
- pub struct CompileResult {
48
- pub code: String,
49
- pub ssr_code: Option<String>,
50
- pub ast: Node,
51
- pub tokens: Vec<Token>,
52
- pub warnings: Vec<CompileWarning>,
53
- }
54
-
55
- pub fn compile(source: &str, options: CompileOptions) -> Result<CompileResult, CompileError> {
56
- let tokens = tokenize(source).map_err(|e| rethrow(e, &options.filename))?;
57
-
58
- let ast = parse(tokens.clone(), source, &options.components)
59
- .map_err(|e| rethrow(e, &options.filename))?;
60
-
61
- let transform_opts = TransformOptions {
62
- components: options.components.clone(),
63
- source: source.to_string(),
64
- scope: options.scope.clone(),
65
- };
66
- let (ast, warnings) = transform(ast, transform_opts);
67
-
68
- if options.throw_on_warning {
69
- if let Some(w) = warnings.first() {
70
- return Err(CompileError::new(w.code, w.loc.clone(), source, &[]));
71
- }
72
- }
73
-
74
- let root = match &ast {
75
- Node::Root(r) => r,
76
- _ => unreachable!("parse() always produces a Root node"),
77
- };
78
-
79
- let code: String;
80
- let mut ssr_code: Option<String> = None;
81
-
82
- match options.target {
83
- CompileTarget::Client => {
84
- code = generate(
85
- root,
86
- GenerateOptions {
87
- source: source.to_string(),
88
- runtime_path: options.runtime_path.clone(),
89
- },
90
- )
91
- .map_err(|e| rethrow(e, &options.filename))?;
92
- }
93
- CompileTarget::SSR => {
94
- let ssr = generate_ssr(
95
- root,
96
- SSRGenerateOptions {
97
- source: source.to_string(),
98
- runtime_path: options
99
- .ssr_runtime_path
100
- .clone()
101
- .or_else(|| options.runtime_path.clone()),
102
- },
103
- )
104
- .map_err(|e| rethrow(e, &options.filename))?;
105
- code = ssr.clone();
106
- ssr_code = Some(ssr);
107
- }
108
- CompileTarget::Both => {
109
- code = generate(
110
- root,
111
- GenerateOptions {
112
- source: source.to_string(),
113
- runtime_path: options.runtime_path.clone(),
114
- },
115
- )
116
- .map_err(|e| rethrow(e, &options.filename))?;
117
-
118
- let ssr = generate_ssr(
119
- root,
120
- SSRGenerateOptions {
121
- source: source.to_string(),
122
- runtime_path: options
123
- .ssr_runtime_path
124
- .clone()
125
- .or_else(|| options.runtime_path.clone()),
126
- },
127
- )
128
- .map_err(|e| rethrow(e, &options.filename))?;
129
- ssr_code = Some(ssr);
130
- }
131
- }
132
-
133
- Ok(CompileResult {
134
- code,
135
- ssr_code,
136
- ast,
137
- tokens,
138
- warnings,
139
- })
140
- }
141
-
142
- pub fn parse_only(source: &str, components: &HashSet<String>) -> Result<(Node, Vec<Token>), CompileError> {
143
- let tokens = tokenize(source)?;
144
- let ast = parse(tokens.clone(), source, components)?;
145
- Ok((ast, tokens))
146
- }
147
-
148
- pub fn transform_only(ast: Node, components: HashSet<String>, source: String, scope: HashSet<String>) -> (Node, Vec<CompileWarning>) {
149
- transform(
150
- ast,
151
- TransformOptions {
152
- components,
153
- source,
154
- scope,
155
- },
156
- )
157
- }
158
-
159
- fn rethrow(err: CompileError, filename: &str) -> CompileError {
160
- let formatted = err.format(filename);
161
- CompileError {
162
- message: formatted,
163
- ..err
164
- }
165
- }