swc_ecma_lexer/
error.rs

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/// Note: this struct is 8 bytes.
12#[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    /// "implements", "interface", "let", "package", "private", "protected",
101    /// "public", "static", or "yield"
102    InvalidIdentInStrict(Atom),
103
104    InvalidIdentInAsync,
105    /// 'eval' and 'arguments' are invalid identifier in strict mode.
106    EvalAndArgumentsInStrict,
107    ArgumentsInClassField,
108    IllegalLanguageModeDirective,
109    UnaryInExp {
110        left: String,
111        left_span: Span,
112    },
113    Hash,
114    LineBreakInThrow,
115    LineBreakBeforeArrow,
116
117    /// Unexpected token
118    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        /// Span of the previous default case
139        previous: Span,
140    },
141    CommaAfterRestElement,
142    NonLastRestParam,
143    SpreadInParenExpr,
144    /// `()`
145    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            // TODO
401            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}