1#![allow(dead_code)]
2
3use std::{borrow::Cow, fmt::Debug};
4
5use swc_atoms::Atom;
6use swc_common::{
7 errors::{DiagnosticBuilder, Handler},
8 Span, Spanned,
9};
10
11#[derive(Debug, Clone, PartialEq)]
13pub struct Error {
14 error: Box<(Span, SyntaxError)>,
15}
16
17impl Spanned for Error {
18 fn span(&self) -> Span {
19 (*self.error).0
20 }
21}
22
23impl Error {
24 #[cold]
25 pub fn new(span: Span, error: SyntaxError) -> Self {
26 Self {
27 error: Box::new((span, error)),
28 }
29 }
30
31 pub fn kind(&self) -> &SyntaxError {
32 &self.error.1
33 }
34
35 pub fn into_kind(self) -> SyntaxError {
36 self.error.1
37 }
38}
39
40#[derive(Debug, Clone, PartialEq)]
41#[non_exhaustive]
42pub enum SyntaxError {
43 Eof,
44 DeclNotAllowed,
45
46 UsingDeclNotAllowed,
47 UsingDeclNotAllowedForForInLoop,
48 UsingDeclNotEnabled,
49 InvalidNameInUsingDecl,
50 InitRequiredForUsingDecl,
51
52 PrivateNameInInterface,
53
54 InvalidSuperCall,
55 InvalidSuper,
56 InvalidSuperPrivateName,
57
58 InvalidNewTarget,
59
60 InvalidImport,
61
62 ArrowNotAllowed,
63 ExportNotAllowed,
64 GetterSetterCannotBeReadonly,
65 GetterSetterCannotBeOptional,
66 GetterParam,
67 SetterParam,
68
69 TopLevelAwaitInScript,
70
71 LegacyDecimal,
72 LegacyOctal,
73 InvalidIdentChar,
74 ExpectedDigit {
75 radix: u8,
76 },
77 SetterParamRequired,
78 RestPatInSetter,
79
80 UnterminatedBlockComment,
81 UnterminatedStrLit,
82 ExpectedUnicodeEscape,
83 EscapeInReservedWord {
84 word: Atom,
85 },
86 UnterminatedRegExp,
87 UnterminatedTpl,
88 IdentAfterNum,
89 UnexpectedChar {
90 c: char,
91 },
92 InvalidStrEscape,
93 InvalidUnicodeEscape,
94 BadCharacterEscapeSequence {
95 expected: &'static str,
96 },
97 NumLitTerminatedWithExp,
98 LegacyCommentInModule,
99
100 InvalidIdentInStrict(Atom),
103
104 InvalidIdentInAsync,
105 EvalAndArgumentsInStrict,
107 ArgumentsInClassField,
108 IllegalLanguageModeDirective,
109 UnaryInExp {
110 left: String,
111 left_span: Span,
112 },
113 Hash,
114 LineBreakInThrow,
115 LineBreakBeforeArrow,
116
117 Unexpected {
119 got: String,
120 expected: &'static str,
121 },
122 UnexpectedTokenWithSuggestions {
123 candidate_list: Vec<&'static str>,
124 },
125 ReservedWordInImport,
126 AssignProperty,
127 Expected(String, String),
128 ExpectedSemiForExprStmt {
129 expr: Span,
130 },
131
132 AwaitStar,
133 ReservedWordInObjShorthandOrPat,
134
135 NullishCoalescingWithLogicalOp,
136
137 MultipleDefault {
138 previous: Span,
140 },
141 CommaAfterRestElement,
142 NonLastRestParam,
143 SpreadInParenExpr,
144 EmptyParenExpr,
146 InvalidPat,
147 InvalidExpr,
148 NotSimpleAssign,
149 InvalidAssignTarget,
150 ExpectedIdent,
151 ExpectedSemi,
152 DuplicateLabel(Atom),
153 AsyncGenerator,
154 NonTopLevelImportExport,
155 ImportExportInScript,
156 ImportMetaInScript,
157 PatVarWithoutInit,
158 WithInStrict,
159 ReturnNotAllowed,
160 TooManyVarInForInHead,
161 VarInitializerInForInHead,
162 LabelledGeneratorOrAsync,
163 LabelledFunctionInStrict,
164 YieldParamInGen,
165 AwaitParamInAsync,
166
167 AwaitForStmt,
168
169 AwaitInFunction,
170
171 UnterminatedJSXContents,
172 EmptyJSXAttr,
173 InvalidJSXValue,
174 JSXExpectedClosingTagForLtGt,
175 JSXExpectedClosingTag {
176 tag: Atom,
177 },
178 InvalidLeadingDecorator,
179 DecoratorOnExport,
180
181 TsRequiredAfterOptional,
182 TsInvalidParamPropPat,
183
184 SpaceBetweenHashAndIdent,
185
186 AsyncConstructor,
187 PropertyNamedConstructor,
188 PrivateConstructor,
189 PrivateNameModifier(Atom),
190 ConstructorAccessor,
191 ReadOnlyMethod,
192 GeneratorConstructor,
193 DuplicateConstructor,
194 TsBindingPatCannotBeOptional,
195 SuperCallOptional,
196 OptChainCannotFollowConstructorCall,
197 TaggedTplInOptChain,
198
199 TrailingCommaInsideImport,
200
201 ExportDefaultWithOutFrom,
202 ExportExpectFrom(Atom),
203
204 DotsWithoutIdentifier,
205
206 NumericSeparatorIsAllowedOnlyBetweenTwoDigits,
207
208 ImportBindingIsString(Atom),
209 ExportBindingIsString,
210
211 ConstDeclarationsRequireInitialization,
212
213 DuplicatedRegExpFlags(char),
214 UnknownRegExpFlags,
215
216 TS1003,
217 TS1005,
218 TS1009,
219 TS1014,
220 TS1015,
221 TS1029(Atom, Atom),
222 TS1030(Atom),
223 TS1031,
224 TS1038,
225 TS1042,
226 TS1047,
227 TS1048,
228 TS1056,
229 TS1085,
230 TS1089(Atom),
231 TS1092,
232 TS1096,
233 TS1098,
234 TS1100,
235 TS1102,
236 TS1105,
237 TS1106,
238 TS1107,
239 TS1109,
240 TS1110,
241 TS1114,
242 TS1115,
243 TS1116,
244 TS1123,
245 TS1141,
246 TS1162,
247 TS1164,
248 TS1171,
249 TS1172,
250 TS1173,
251 TS1174,
252 TS1175,
253 TS1183,
254 TS1184,
255 TS1185,
256 TS1093,
257 TS1196,
258 TS1242,
259 TS1243(Atom, Atom),
260 TS1244,
261 TS1245,
262 TS1267,
263 TS1273(Atom),
264 TS1274(Atom),
265 TS1277(Atom),
266 TS2206,
267 TS2207,
268 TS2369,
269 TS2371,
270 TS2406,
271 TS2410,
272 TS2414,
273 TS2427,
274 TS2452,
275 TS2483,
276 TS2491,
277 TS2499,
278 TS2703,
279 TS4112,
280 TS8038,
281 TS18010,
282 TSTypeAnnotationAfterAssign,
283 TsNonNullAssertionNotAllowed(Atom),
284
285 WithLabel {
286 inner: Box<Error>,
287 span: Span,
288 note: &'static str,
289 },
290
291 ReservedTypeAssertion,
292 ReservedArrowTypeParam,
293}
294
295impl SyntaxError {
296 #[cold]
297 #[inline(never)]
298 pub fn msg(&self) -> Cow<'static, str> {
299 match self {
300 SyntaxError::PrivateNameInInterface => {
301 "private names are not allowed in interface".into()
302 }
303 SyntaxError::TopLevelAwaitInScript => {
304 "top level await is only allowed in module".into()
305 }
306 SyntaxError::LegacyDecimal => {
307 "Legacy decimal escape is not permitted in strict mode".into()
308 }
309 SyntaxError::LegacyOctal => {
310 "Legacy octal escape is not permitted in strict mode".into()
311 }
312 SyntaxError::InvalidIdentChar => "Invalid character in identifier".into(),
313 SyntaxError::ExpectedDigit { radix } => format!(
314 "Expected {} digit",
315 match radix {
316 2 => "a binary",
317 8 => "an octal",
318 10 => "a decimal",
319 16 => "a hexadecimal",
320 _ => unreachable!(),
321 }
322 )
323 .into(),
324 SyntaxError::UnterminatedBlockComment => "Unterminated block comment".into(),
325 SyntaxError::UnterminatedStrLit => "Unterminated string constant".into(),
326 SyntaxError::ExpectedUnicodeEscape => "Expected unicode escape".into(),
327 SyntaxError::EscapeInReservedWord { ref word } => {
328 format!("Unexpected escape sequence in reserved word: {word}").into()
329 }
330 SyntaxError::UnterminatedRegExp => "Unterminated regexp literal".into(),
331 SyntaxError::UnterminatedTpl => "Unterminated template".into(),
332 SyntaxError::IdentAfterNum => "Identifier cannot follow number".into(),
333 SyntaxError::UnexpectedChar { c } => format!("Unexpected character {c:?}").into(),
334 SyntaxError::InvalidStrEscape => "Invalid string escape".into(),
335 SyntaxError::InvalidUnicodeEscape => "Invalid unicode escape".into(),
336 SyntaxError::BadCharacterEscapeSequence { expected } => {
337 format!("Bad character escape sequence, expected {expected}").into()
338 }
339 SyntaxError::LegacyCommentInModule => {
340 "Legacy comments cannot be used in module code".into()
341 }
342 SyntaxError::NumLitTerminatedWithExp => "Expected +, - or decimal digit after e".into(),
343
344 SyntaxError::InvalidIdentInStrict(identifier_name) => {
345 format!("`{identifier_name}` cannot be used as an identifier in strict mode").into()
346 }
347 SyntaxError::InvalidIdentInAsync => {
348 "`await` cannot be used as an identifier in an async context".into()
349 }
350 SyntaxError::EvalAndArgumentsInStrict => "'eval' and 'arguments' cannot be used as a \
351 binding identifier in strict mode"
352 .into(),
353 SyntaxError::ArgumentsInClassField => {
354 "'arguments' is only allowed in functions and class methods".into()
355 }
356 SyntaxError::IllegalLanguageModeDirective => {
357 "Illegal 'use strict' directive in function with non-simple parameter list.".into()
358 }
359 SyntaxError::UnaryInExp { .. } => {
360 "'**' cannot be applied to unary/await expression.".into()
361 }
362 SyntaxError::Hash => "Unexpected token '#'".into(),
363 SyntaxError::LineBreakInThrow => "LineBreak cannot follow 'throw'".into(),
364 SyntaxError::LineBreakBeforeArrow => {
365 "Unexpected line break between arrow head and arrow".into()
366 }
367 SyntaxError::Unexpected {
368 ref got,
369 ref expected,
370 } => format!("Unexpected token `{got}`. Expected {expected}").into(),
371
372 SyntaxError::ReservedWordInImport => "cannot import as reserved word".into(),
373 SyntaxError::AssignProperty => "assignment property is invalid syntax".into(),
374 SyntaxError::Expected(token, ref got) => {
375 format!("Expected '{token}', got '{got}'").into()
376 }
377 SyntaxError::ExpectedSemiForExprStmt { .. } => "Expected ';', '}' or <eof>".into(),
378
379 SyntaxError::AwaitStar => "await* has been removed from the async functions proposal. \
380 Use Promise.all() instead."
381 .into(),
382
383 SyntaxError::ReservedWordInObjShorthandOrPat => {
384 "Cannot use a reserved word as a shorthand property".into()
385 }
386
387 SyntaxError::MultipleDefault { .. } => {
388 "A switch block cannot have multiple defaults".into()
389 }
390 SyntaxError::CommaAfterRestElement => {
391 "Trailing comma isn't permitted after a rest element".into()
392 }
393 SyntaxError::NonLastRestParam => "Rest element must be final element".into(),
394 SyntaxError::SpreadInParenExpr => {
395 "Parenthesized expression cannot contain spread operator".into()
396 }
397 SyntaxError::EmptyParenExpr => "Parenthesized expression cannot be empty".into(),
398 SyntaxError::InvalidPat => "Not a pattern".into(),
399 SyntaxError::InvalidExpr => "Not an expression".into(),
400 SyntaxError::NotSimpleAssign => "Cannot assign to this".into(),
402 SyntaxError::ExpectedIdent => "Expected ident".into(),
403 SyntaxError::ExpectedSemi => "Expected ';' or line break".into(),
404 SyntaxError::DuplicateLabel(ref label) => {
405 format!("Label {label} is already declared").into()
406 }
407 SyntaxError::AsyncGenerator => "An async function cannot be generator".into(),
408 SyntaxError::NonTopLevelImportExport => {
409 "'import', and 'export' are not permitted here".into()
410 }
411 SyntaxError::ImportExportInScript => {
412 "'import', and 'export' cannot be used outside of module code".into()
413 }
414 SyntaxError::ImportMetaInScript => {
415 "'import.meta' cannot be used outside of module code.".into()
416 }
417
418 SyntaxError::PatVarWithoutInit => "Destructuring bindings require initializers".into(),
419 SyntaxError::WithInStrict => "With statement are not allowed in strict mode".into(),
420 SyntaxError::ReturnNotAllowed => "Return statement is not allowed here".into(),
421 SyntaxError::TooManyVarInForInHead => "Expected one variable binding".into(),
422 SyntaxError::VarInitializerInForInHead => {
423 "Unexpected initializer in for in/of loop".into()
424 }
425 SyntaxError::LabelledGeneratorOrAsync => {
426 "Generator or async function cannot be labelled".into()
427 }
428 SyntaxError::LabelledFunctionInStrict => {
429 "Function cannot be labelled in strict mode".into()
430 }
431 SyntaxError::YieldParamInGen => {
432 "'yield' cannot be used as a parameter within generator".into()
433 }
434 SyntaxError::AwaitParamInAsync => {
435 "`await` expressions cannot be used in a parameter initializer.".into()
436 }
437 SyntaxError::AwaitForStmt => {
438 "for await syntax is valid only for for-of statement".into()
439 }
440
441 SyntaxError::AwaitInFunction => "await isn't allowed in non-async function".into(),
442
443 SyntaxError::UnterminatedJSXContents => "Unterminated JSX contents".into(),
444 SyntaxError::EmptyJSXAttr => {
445 "JSX attributes must only be assigned a non-empty expression".into()
446 }
447 SyntaxError::InvalidJSXValue => {
448 "JSX value should be either an expression or a quoted JSX text".into()
449 }
450 SyntaxError::JSXExpectedClosingTagForLtGt => {
451 "Expected corresponding JSX closing tag for <>".into()
452 }
453 SyntaxError::JSXExpectedClosingTag { ref tag } => {
454 format!("Expected corresponding JSX closing tag for <{tag}>").into()
455 }
456 SyntaxError::InvalidLeadingDecorator => {
457 "Leading decorators must be attached to a class declaration".into()
458 }
459 SyntaxError::DecoratorOnExport => "Using the export keyword between a decorator and a \
460 class is not allowed. Please use `export @dec \
461 class` instead."
462 .into(),
463 SyntaxError::TsRequiredAfterOptional => {
464 "A required element cannot follow an optional element.".into()
465 }
466 SyntaxError::SuperCallOptional => "Super call cannot be optional".into(),
467 SyntaxError::OptChainCannotFollowConstructorCall => {
468 "Constructor in/after an optional chaining is not allowed.".into()
469 }
470 SyntaxError::TaggedTplInOptChain => {
471 "Tagged template literal is not allowed in optional chain.".into()
472 }
473 SyntaxError::TsInvalidParamPropPat => {
474 "Typescript parameter property must be an identifier or assignment pattern".into()
475 }
476 SyntaxError::SpaceBetweenHashAndIdent => {
477 "Unexpected space between # and identifier".into()
478 }
479 SyntaxError::AsyncConstructor => "Constructor can't be an async function".into(),
480 SyntaxError::PropertyNamedConstructor => {
481 "Classes may not have a non-static field named 'constructor'".into()
482 }
483 SyntaxError::PrivateConstructor => {
484 "Classes can't have a private field named '#constructor'.".into()
485 }
486 SyntaxError::DuplicateConstructor => "A class can only have one constructor".into(),
487 SyntaxError::PrivateNameModifier(modifier) => {
488 format!("'{modifier}' modifier cannot be used with a private identifier").into()
489 }
490 SyntaxError::ConstructorAccessor => "Class constructor can't be an accessor.".into(),
491
492 SyntaxError::ReadOnlyMethod => "A method cannot be readonly".into(),
493 SyntaxError::TsBindingPatCannotBeOptional => "A binding pattern parameter cannot be \
494 optional in an implementation signature."
495 .into(),
496
497 SyntaxError::TrailingCommaInsideImport => {
498 "Trailing comma is disallowed inside import(...) arguments".into()
499 }
500
501 SyntaxError::ExportDefaultWithOutFrom => {
502 "export default statements required from '...';".into()
503 }
504
505 SyntaxError::ExportExpectFrom(s) => {
506 format!("`{s}` cannot be used without `from` clause").into()
507 }
508
509 SyntaxError::DotsWithoutIdentifier => {
510 "`...` must be followed by an identifier in declaration contexts".into()
511 }
512
513 SyntaxError::NumericSeparatorIsAllowedOnlyBetweenTwoDigits => {
514 "A numeric separator is only allowed between two digits".into()
515 }
516
517 SyntaxError::NullishCoalescingWithLogicalOp => {
518 "Nullish coalescing operator(??) requires parens when mixing with logical operators"
519 .into()
520 }
521
522 SyntaxError::TS1056 => {
523 "jsc.target should be es5 or upper to use getter / setter".into()
524 }
525 SyntaxError::TS1110 => "type expected".into(),
526 SyntaxError::TS1141 => "literal in an import type should be string literal".into(),
527
528 SyntaxError::Eof => "Unexpected eof".into(),
529
530 SyntaxError::TS2703 => {
531 "The operand of a delete operator must be a property reference.".into()
532 }
533 SyntaxError::DeclNotAllowed => "Declaration is not allowed".into(),
534 SyntaxError::UsingDeclNotAllowed => "Using declaration is not allowed".into(),
535 SyntaxError::UsingDeclNotAllowedForForInLoop => {
536 "Using declaration is not allowed in for-in loop".into()
537 }
538 SyntaxError::UsingDeclNotEnabled => "Using declaration is not enabled. Set \
539 jsc.parser.explicitResourceManagement to true"
540 .into(),
541 SyntaxError::InvalidNameInUsingDecl => {
542 "Using declaration only allows identifiers".into()
543 }
544 SyntaxError::InitRequiredForUsingDecl => {
545 "Using declaration requires initializer".into()
546 }
547 SyntaxError::InvalidSuperCall => "Invalid `super()`".into(),
548 SyntaxError::InvalidSuper => "Invalid access to super".into(),
549 SyntaxError::InvalidSuperPrivateName => {
550 "Index super with private name is not allowed".into()
551 }
552 SyntaxError::InvalidNewTarget => "'new.target' is only allowed in the body of a \
553 function declaration, function expression, or class."
554 .into(),
555 SyntaxError::InvalidImport => "Import is not allowed here".into(),
556 SyntaxError::ArrowNotAllowed => "An arrow function is not allowed here".into(),
557 SyntaxError::ExportNotAllowed => "`export` is not allowed here".into(),
558 SyntaxError::GetterSetterCannotBeReadonly => {
559 "A getter or a setter cannot be readonly".into()
560 }
561 SyntaxError::GetterSetterCannotBeOptional => {
562 "A getter or a setter cannot be optional".into()
563 }
564 SyntaxError::GetterParam => "A `get` accessor cannot have parameters".into(),
565 SyntaxError::SetterParam => "A `set` accessor must have exactly one parameter".into(),
566 SyntaxError::RestPatInSetter => "Rest pattern is not allowed in setter".into(),
567
568 SyntaxError::GeneratorConstructor => "A constructor cannot be generator".into(),
569
570 SyntaxError::ImportBindingIsString(s) => format!(
571 "A string literal cannot be used as an imported binding.\n- Did you mean `import \
572 {{ \"{s}\" as foo }}`?"
573 )
574 .into(),
575
576 SyntaxError::ExportBindingIsString => {
577 "A string literal cannot be used as an exported binding without `from`.".into()
578 }
579
580 SyntaxError::ConstDeclarationsRequireInitialization => {
581 "'const' declarations must be initialized".into()
582 }
583
584 SyntaxError::DuplicatedRegExpFlags(flag) => {
585 format!("Duplicated regular expression flag '{flag}'.").into()
586 }
587 SyntaxError::UnknownRegExpFlags => "Unknown regular expression flags.".into(),
588
589 SyntaxError::TS1003 => "Expected an identifier".into(),
590 SyntaxError::TS1005 => "Expected a semicolon".into(),
591 SyntaxError::TS1009 => "Trailing comma is not allowed".into(),
592 SyntaxError::TS1014 => "A rest parameter must be last in a parameter list".into(),
593 SyntaxError::TS1015 => "Parameter cannot have question mark and initializer".into(),
594 SyntaxError::TS1029(left, right) => {
595 format!("'{left}' modifier must precede '{right}' modifier.").into()
596 }
597 SyntaxError::TS1030(word) => format!("'{word}' modifier already seen.").into(),
598 SyntaxError::TS1031 => {
599 "`declare` modifier cannot appear on class elements of this kind".into()
600 }
601 SyntaxError::TS1038 => {
602 "`declare` modifier not allowed for code already in an ambient context".into()
603 }
604 SyntaxError::TS1042 => "`async` modifier cannot be used here".into(),
605 SyntaxError::TS1047 => "A rest parameter cannot be optional".into(),
606 SyntaxError::TS1048 => "A rest parameter cannot have an initializer".into(),
607 SyntaxError::TS1085 => "Legacy octal literals are not available when targeting \
608 ECMAScript 5 and higher"
609 .into(),
610 SyntaxError::TS1089(word) => {
611 format!("'{word}' modifier cannot appear on a constructor declaration").into()
612 }
613 SyntaxError::TS1092 => {
614 "Type parameters cannot appear on a constructor declaration".into()
615 }
616 SyntaxError::TS1096 => "An index signature must have exactly one parameter".into(),
617 SyntaxError::TS1098 => "Type parameter list cannot be empty".into(),
618 SyntaxError::TS1100 => "Invalid use of 'arguments' in strict mode".into(),
619 SyntaxError::TS1102 => {
620 "'delete' cannot be called on an identifier in strict mode".into()
621 }
622 SyntaxError::TS1105 => "A 'break' statement can only be used within an enclosing \
623 iteration or switch statement"
624 .into(),
625 SyntaxError::TS1106 => {
626 "The left-hand side of a `for...of` statement may not be `async`".into()
627 }
628 SyntaxError::TS1107 => "Jump target cannot cross function boundary".into(),
629 SyntaxError::TS1109 => "Expression expected".into(),
630 SyntaxError::TS1114 => "Duplicate label".into(),
631 SyntaxError::TS1115 => "A 'continue' statement can only jump to a label of an \
632 enclosing iteration statement"
633 .into(),
634 SyntaxError::TS1116 => {
635 "A 'break' statement can only jump to a label of an enclosing statement".into()
636 }
637 SyntaxError::TS1123 => "Variable declaration list cannot be empty".into(),
638 SyntaxError::TS1162 => "An object member cannot be declared optional".into(),
639 SyntaxError::TS1164 => "Computed property names are not allowed in enums".into(),
640 SyntaxError::TS1171 => {
641 "A comma expression is not allowed in a computed property name".into()
642 }
643 SyntaxError::TS1172 => "`extends` clause already seen.".into(),
644 SyntaxError::TS1173 => "'extends' clause must precede 'implements' clause.".into(),
645 SyntaxError::TS1174 => "Classes can only extend a single class".into(),
646 SyntaxError::TS1175 => "`implements` clause already seen".into(),
647 SyntaxError::TS1183 => {
648 "An implementation cannot be declared in ambient contexts".into()
649 }
650 SyntaxError::TS1184 => "Modifiers cannot appear here".into(),
651 SyntaxError::TS1185 => "Merge conflict marker encountered.".into(),
652 SyntaxError::TS1093 => {
653 "Type annotation cannot appear on a constructor declaration".into()
654 }
655 SyntaxError::TS1196 => "Catch clause variable cannot have a type annotation".into(),
656 SyntaxError::TS1242 => {
657 "`abstract` modifier can only appear on a class or method declaration".into()
658 }
659 SyntaxError::TS1244 => {
660 "Abstract methods can only appear within an abstract class.".into()
661 }
662 SyntaxError::TS1243(left, right) => {
663 format!("'{left}' modifier cannot be used with '{right}' modifier.").into()
664 }
665 SyntaxError::TS1245 => "Abstract method cannot have an implementation.".into(),
666 SyntaxError::TS1267 => "Abstract property cannot have an initializer.".into(),
667 SyntaxError::TS1273(word) => {
668 format!("'{word}' modifier cannot appear on a type parameter").into()
669 }
670 SyntaxError::TS1274(word) => format!(
671 "'{word}' modifier can only appear on a type parameter of a class, interface or \
672 type alias"
673 )
674 .into(),
675 SyntaxError::TS1277(word) => format!(
676 "'{word}' modifier can only appear on a type parameter of a function, method or \
677 class"
678 )
679 .into(),
680 SyntaxError::TS2206 => "The 'type' modifier cannot be used on a named import when \
681 'import type' is used on its import statement."
682 .into(),
683 SyntaxError::TS2207 => "The 'type' modifier cannot be used on a named export when \
684 'export type' is used on its export statement."
685 .into(),
686 SyntaxError::TS2369 => {
687 "A parameter property is only allowed in a constructor implementation".into()
688 }
689 SyntaxError::TS2371 => "A parameter initializer is only allowed in a function or \
690 constructor implementation"
691 .into(),
692 SyntaxError::TS2406 => "The left-hand side of an assignment expression must be a \
693 variable or a property access."
694 .into(),
695 SyntaxError::TS2410 => "The 'with' statement is not supported. All symbols in a \
696 'with' block will have type 'any'."
697 .into(),
698 SyntaxError::TS2414 => "Invalid class name".into(),
699 SyntaxError::TS2427 => "interface name is invalid".into(),
700 SyntaxError::TS2452 => "An enum member cannot have a numeric name".into(),
701 SyntaxError::TS2483 => {
702 "The left-hand side of a 'for...of' statement cannot use a type annotation".into()
703 }
704 SyntaxError::TS2491 => "The left-hand side of a 'for...in' statement cannot be a \
705 destructuring pattern"
706 .into(),
707 SyntaxError::TS2499 => "An interface can only extend an identifier/qualified-name \
708 with optional type arguments."
709 .into(),
710 SyntaxError::TS4112 => "This member cannot have an 'override' modifier because its \
711 containing class does not extend another class."
712 .into(),
713 SyntaxError::TS8038 => "Decorators may not appear after `export` or `export default` \
714 if they also appear before `export`."
715 .into(),
716 SyntaxError::TS18010 => {
717 "An accessibility modifier cannot be used with a private identifier.".into()
718 }
719 SyntaxError::TSTypeAnnotationAfterAssign => {
720 "Type annotations must come before default assignments".into()
721 }
722 SyntaxError::TsNonNullAssertionNotAllowed(word) => {
723 format!("Typescript non-null assertion operator is not allowed with '{word}'")
724 .into()
725 }
726 SyntaxError::SetterParamRequired => "Setter should have exactly one parameter".into(),
727 SyntaxError::UnexpectedTokenWithSuggestions {
728 candidate_list: token_list,
729 } => {
730 let did_you_mean = if token_list.len() <= 2 {
731 token_list.join(" or ")
732 } else {
733 token_list[0..token_list.len() - 1].join(" , ")
734 + &*format!("or {}", token_list[token_list.len() - 1])
735 };
736 format!("Unexpected token. Did you mean {did_you_mean}?").into()
737 }
738 SyntaxError::WithLabel { inner, .. } => inner.error.1.msg(),
739 SyntaxError::ReservedTypeAssertion => "This syntax is reserved in files with the .mts \
740 or .cts extension. Use an `as` expression \
741 instead."
742 .into(),
743 SyntaxError::ReservedArrowTypeParam => "This syntax is reserved in files with the \
744 .mts or .cts extension. Add a trailing comma, \
745 as in `<T,>() => ...`."
746 .into(),
747 SyntaxError::InvalidAssignTarget => "Invalid assignment target".into(),
748 }
749 }
750}
751
752impl Error {
753 #[cold]
754 #[inline(never)]
755 pub fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder {
756 if let SyntaxError::WithLabel { inner, note, span } = self.error.1 {
757 let mut db = inner.into_diagnostic(handler);
758 db.span_label(span, note);
759 return db;
760 }
761
762 let span = self.span();
763
764 let kind = self.into_kind();
765 let msg = kind.msg();
766
767 let mut db = handler.struct_span_err(span, &msg);
768
769 match kind {
770 SyntaxError::ExpectedSemiForExprStmt { expr } => {
771 db.span_label(
772 expr,
773 "This is the expression part of an expression statement",
774 );
775 }
776 SyntaxError::MultipleDefault { previous } => {
777 db.span_label(previous, "previous default case is declared at here");
778 }
779 _ => {}
780 }
781
782 db
783 }
784}
785
786#[test]
787fn size_of_error() {
788 assert_eq!(std::mem::size_of::<Error>(), 8);
789}