swc_ecma_parser/
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    EmptyTypeArgumentList,
294}
295
296impl SyntaxError {
297    #[cold]
298    #[inline(never)]
299    pub fn msg(&self) -> Cow<'static, str> {
300        match self {
301            SyntaxError::PrivateNameInInterface => {
302                "private names are not allowed in interface".into()
303            }
304            SyntaxError::TopLevelAwaitInScript => {
305                "top level await is only allowed in module".into()
306            }
307            SyntaxError::LegacyDecimal => {
308                "Legacy decimal escape is not permitted in strict mode".into()
309            }
310            SyntaxError::LegacyOctal => {
311                "Legacy octal escape is not permitted in strict mode".into()
312            }
313            SyntaxError::InvalidIdentChar => "Invalid character in identifier".into(),
314            SyntaxError::ExpectedDigit { radix } => format!(
315                "Expected {} digit",
316                match radix {
317                    2 => "a binary",
318                    8 => "an octal",
319                    10 => "a decimal",
320                    16 => "a hexadecimal",
321                    _ => unreachable!(),
322                }
323            )
324            .into(),
325            SyntaxError::UnterminatedBlockComment => "Unterminated block comment".into(),
326            SyntaxError::UnterminatedStrLit => "Unterminated string constant".into(),
327            SyntaxError::ExpectedUnicodeEscape => "Expected unicode escape".into(),
328            SyntaxError::EscapeInReservedWord { ref word } => {
329                format!("Unexpected escape sequence in reserved word: {word}").into()
330            }
331            SyntaxError::UnterminatedRegExp => "Unterminated regexp literal".into(),
332            SyntaxError::UnterminatedTpl => "Unterminated template".into(),
333            SyntaxError::IdentAfterNum => "Identifier cannot follow number".into(),
334            SyntaxError::UnexpectedChar { c } => format!("Unexpected character {c:?}").into(),
335            SyntaxError::InvalidStrEscape => "Invalid string escape".into(),
336            SyntaxError::InvalidUnicodeEscape => "Invalid unicode escape".into(),
337            SyntaxError::BadCharacterEscapeSequence { expected } => {
338                format!("Bad character escape sequence, expected {expected}").into()
339            }
340            SyntaxError::LegacyCommentInModule => {
341                "Legacy comments cannot be used in module code".into()
342            }
343            SyntaxError::NumLitTerminatedWithExp => "Expected +, - or decimal digit after e".into(),
344
345            SyntaxError::InvalidIdentInStrict(identifier_name) => {
346                format!("`{identifier_name}` cannot be used as an identifier in strict mode").into()
347            }
348            SyntaxError::InvalidIdentInAsync => {
349                "`await` cannot be used as an identifier in an async context".into()
350            }
351            SyntaxError::EvalAndArgumentsInStrict => "'eval' and 'arguments' cannot be used as a \
352                                                      binding identifier in strict mode"
353                .into(),
354            SyntaxError::ArgumentsInClassField => {
355                "'arguments' is only allowed in functions and class methods".into()
356            }
357            SyntaxError::IllegalLanguageModeDirective => {
358                "Illegal 'use strict' directive in function with non-simple parameter list.".into()
359            }
360            SyntaxError::UnaryInExp { .. } => {
361                "'**' cannot be applied to unary/await expression.".into()
362            }
363            SyntaxError::Hash => "Unexpected token '#'".into(),
364            SyntaxError::LineBreakInThrow => "LineBreak cannot follow 'throw'".into(),
365            SyntaxError::LineBreakBeforeArrow => {
366                "Unexpected line break between arrow head and arrow".into()
367            }
368            SyntaxError::Unexpected {
369                ref got,
370                ref expected,
371            } => format!("Unexpected token `{got}`. Expected {expected}").into(),
372
373            SyntaxError::ReservedWordInImport => "cannot import as reserved word".into(),
374            SyntaxError::AssignProperty => "assignment property is invalid syntax".into(),
375            SyntaxError::Expected(token, ref got) => {
376                format!("Expected '{token}', got '{got}'").into()
377            }
378            SyntaxError::ExpectedSemiForExprStmt { .. } => "Expected ';', '}' or <eof>".into(),
379
380            SyntaxError::AwaitStar => "await* has been removed from the async functions proposal. \
381                                       Use Promise.all() instead."
382                .into(),
383
384            SyntaxError::ReservedWordInObjShorthandOrPat => {
385                "Cannot use a reserved word as a shorthand property".into()
386            }
387
388            SyntaxError::MultipleDefault { .. } => {
389                "A switch block cannot have multiple defaults".into()
390            }
391            SyntaxError::CommaAfterRestElement => {
392                "Trailing comma isn't permitted after a rest element".into()
393            }
394            SyntaxError::NonLastRestParam => "Rest element must be final element".into(),
395            SyntaxError::SpreadInParenExpr => {
396                "Parenthesized expression cannot contain spread operator".into()
397            }
398            SyntaxError::EmptyParenExpr => "Parenthesized expression cannot be empty".into(),
399            SyntaxError::InvalidPat => "Not a pattern".into(),
400            SyntaxError::InvalidExpr => "Not an expression".into(),
401            // TODO
402            SyntaxError::NotSimpleAssign => "Cannot assign to this".into(),
403            SyntaxError::ExpectedIdent => "Expected ident".into(),
404            SyntaxError::ExpectedSemi => "Expected ';' or line break".into(),
405            SyntaxError::DuplicateLabel(ref label) => {
406                format!("Label {label} is already declared").into()
407            }
408            SyntaxError::AsyncGenerator => "An async function cannot be generator".into(),
409            SyntaxError::NonTopLevelImportExport => {
410                "'import', and 'export' are not permitted here".into()
411            }
412            SyntaxError::ImportExportInScript => {
413                "'import', and 'export' cannot be used outside of module code".into()
414            }
415            SyntaxError::ImportMetaInScript => {
416                "'import.meta' cannot be used outside of module code.".into()
417            }
418
419            SyntaxError::PatVarWithoutInit => "Destructuring bindings require initializers".into(),
420            SyntaxError::WithInStrict => "With statement are not allowed in strict mode".into(),
421            SyntaxError::ReturnNotAllowed => "Return statement is not allowed here".into(),
422            SyntaxError::TooManyVarInForInHead => "Expected one variable binding".into(),
423            SyntaxError::VarInitializerInForInHead => {
424                "Unexpected initializer in for in/of loop".into()
425            }
426            SyntaxError::LabelledGeneratorOrAsync => {
427                "Generator or async function cannot be labelled".into()
428            }
429            SyntaxError::LabelledFunctionInStrict => {
430                "Function cannot be labelled in strict mode".into()
431            }
432            SyntaxError::YieldParamInGen => {
433                "'yield' cannot be used as a parameter within generator".into()
434            }
435            SyntaxError::AwaitParamInAsync => {
436                "`await` expressions cannot be used in a parameter initializer.".into()
437            }
438            SyntaxError::AwaitForStmt => {
439                "for await syntax is valid only for for-of statement".into()
440            }
441
442            SyntaxError::AwaitInFunction => "await isn't allowed in non-async function".into(),
443
444            SyntaxError::UnterminatedJSXContents => "Unterminated JSX contents".into(),
445            SyntaxError::EmptyJSXAttr => {
446                "JSX attributes must only be assigned a non-empty expression".into()
447            }
448            SyntaxError::InvalidJSXValue => {
449                "JSX value should be either an expression or a quoted JSX text".into()
450            }
451            SyntaxError::JSXExpectedClosingTagForLtGt => {
452                "Expected corresponding JSX closing tag for <>".into()
453            }
454            SyntaxError::JSXExpectedClosingTag { ref tag } => {
455                format!("Expected corresponding JSX closing tag for <{tag}>").into()
456            }
457            SyntaxError::InvalidLeadingDecorator => {
458                "Leading decorators must be attached to a class declaration".into()
459            }
460            SyntaxError::DecoratorOnExport => "Using the export keyword between a decorator and a \
461                                               class is not allowed. Please use `export @dec \
462                                               class` instead."
463                .into(),
464            SyntaxError::TsRequiredAfterOptional => {
465                "A required element cannot follow an optional element.".into()
466            }
467            SyntaxError::SuperCallOptional => "Super call cannot be optional".into(),
468            SyntaxError::OptChainCannotFollowConstructorCall => {
469                "Constructor in/after an optional chaining is not allowed.".into()
470            }
471            SyntaxError::TaggedTplInOptChain => {
472                "Tagged template literal is not allowed in optional chain.".into()
473            }
474            SyntaxError::TsInvalidParamPropPat => {
475                "Typescript parameter property must be an identifier or assignment pattern".into()
476            }
477            SyntaxError::SpaceBetweenHashAndIdent => {
478                "Unexpected space between # and identifier".into()
479            }
480            SyntaxError::AsyncConstructor => "Constructor can't be an async function".into(),
481            SyntaxError::PropertyNamedConstructor => {
482                "Classes may not have a non-static field named 'constructor'".into()
483            }
484            SyntaxError::PrivateConstructor => {
485                "Classes can't have a private field named '#constructor'.".into()
486            }
487            SyntaxError::DuplicateConstructor => "A class can only have one constructor".into(),
488            SyntaxError::PrivateNameModifier(modifier) => {
489                format!("'{modifier}' modifier cannot be used with a private identifier").into()
490            }
491            SyntaxError::ConstructorAccessor => "Class constructor can't be an accessor.".into(),
492
493            SyntaxError::ReadOnlyMethod => "A method cannot be readonly".into(),
494            SyntaxError::TsBindingPatCannotBeOptional => "A binding pattern parameter cannot be \
495                                                          optional in an implementation signature."
496                .into(),
497
498            SyntaxError::TrailingCommaInsideImport => {
499                "Trailing comma is disallowed inside import(...) arguments".into()
500            }
501
502            SyntaxError::ExportDefaultWithOutFrom => {
503                "export default statements required from '...';".into()
504            }
505
506            SyntaxError::ExportExpectFrom(s) => {
507                format!("`{s}` cannot be used without `from` clause").into()
508            }
509
510            SyntaxError::DotsWithoutIdentifier => {
511                "`...` must be followed by an identifier in declaration contexts".into()
512            }
513
514            SyntaxError::NumericSeparatorIsAllowedOnlyBetweenTwoDigits => {
515                "A numeric separator is only allowed between two digits".into()
516            }
517
518            SyntaxError::NullishCoalescingWithLogicalOp => {
519                "Nullish coalescing operator(??) requires parens when mixing with logical operators"
520                    .into()
521            }
522
523            SyntaxError::TS1056 => {
524                "jsc.target should be es5 or upper to use getter / setter".into()
525            }
526            SyntaxError::TS1110 => "type expected".into(),
527            SyntaxError::TS1141 => "literal in an import type should be string literal".into(),
528
529            SyntaxError::Eof => "Unexpected eof".into(),
530
531            SyntaxError::TS2703 => {
532                "The operand of a delete operator must be a property reference.".into()
533            }
534            SyntaxError::DeclNotAllowed => "Declaration is not allowed".into(),
535            SyntaxError::UsingDeclNotAllowed => "Using declaration is not allowed".into(),
536            SyntaxError::UsingDeclNotAllowedForForInLoop => {
537                "Using declaration is not allowed in for-in loop".into()
538            }
539            SyntaxError::UsingDeclNotEnabled => "Using declaration is not enabled. Set \
540                                                 jsc.parser.explicitResourceManagement to true"
541                .into(),
542            SyntaxError::InvalidNameInUsingDecl => {
543                "Using declaration only allows identifiers".into()
544            }
545            SyntaxError::InitRequiredForUsingDecl => {
546                "Using declaration requires initializer".into()
547            }
548            SyntaxError::InvalidSuperCall => "Invalid `super()`".into(),
549            SyntaxError::InvalidSuper => "Invalid access to super".into(),
550            SyntaxError::InvalidSuperPrivateName => {
551                "Index super with private name is not allowed".into()
552            }
553            SyntaxError::InvalidNewTarget => "'new.target' is only allowed in the body of a \
554                                              function declaration, function expression, or class."
555                .into(),
556            SyntaxError::InvalidImport => "Import is not allowed here".into(),
557            SyntaxError::ArrowNotAllowed => "An arrow function is not allowed here".into(),
558            SyntaxError::ExportNotAllowed => "`export` is not allowed here".into(),
559            SyntaxError::GetterSetterCannotBeReadonly => {
560                "A getter or a setter cannot be readonly".into()
561            }
562            SyntaxError::GetterSetterCannotBeOptional => {
563                "A getter or a setter cannot be optional".into()
564            }
565            SyntaxError::GetterParam => "A `get` accessor cannot have parameters".into(),
566            SyntaxError::SetterParam => "A `set` accessor must have exactly one parameter".into(),
567            SyntaxError::RestPatInSetter => "Rest pattern is not allowed in setter".into(),
568
569            SyntaxError::GeneratorConstructor => "A constructor cannot be generator".into(),
570
571            SyntaxError::ImportBindingIsString(s) => format!(
572                "A string literal cannot be used as an imported binding.\n- Did you mean `import \
573                 {{ \"{s}\" as foo }}`?"
574            )
575            .into(),
576
577            SyntaxError::ExportBindingIsString => {
578                "A string literal cannot be used as an exported binding without `from`.".into()
579            }
580
581            SyntaxError::ConstDeclarationsRequireInitialization => {
582                "'const' declarations must be initialized".into()
583            }
584
585            SyntaxError::DuplicatedRegExpFlags(flag) => {
586                format!("Duplicated regular expression flag '{flag}'.").into()
587            }
588            SyntaxError::UnknownRegExpFlags => "Unknown regular expression flags.".into(),
589
590            SyntaxError::TS1003 => "Expected an identifier".into(),
591            SyntaxError::TS1005 => "Expected a semicolon".into(),
592            SyntaxError::TS1009 => "Trailing comma is not allowed".into(),
593            SyntaxError::TS1014 => "A rest parameter must be last in a parameter list".into(),
594            SyntaxError::TS1015 => "Parameter cannot have question mark and initializer".into(),
595            SyntaxError::TS1029(left, right) => {
596                format!("'{left}' modifier must precede '{right}' modifier.").into()
597            }
598            SyntaxError::TS1030(word) => format!("'{word}' modifier already seen.").into(),
599            SyntaxError::TS1031 => {
600                "`declare` modifier cannot appear on class elements of this kind".into()
601            }
602            SyntaxError::TS1038 => {
603                "`declare` modifier not allowed for code already in an ambient context".into()
604            }
605            SyntaxError::TS1042 => "`async` modifier cannot be used here".into(),
606            SyntaxError::TS1047 => "A rest parameter cannot be optional".into(),
607            SyntaxError::TS1048 => "A rest parameter cannot have an initializer".into(),
608            SyntaxError::TS1085 => "Legacy octal literals are not available when targeting \
609                                    ECMAScript 5 and higher"
610                .into(),
611            SyntaxError::TS1089(word) => {
612                format!("'{word}' modifier cannot appear on a constructor declaration").into()
613            }
614            SyntaxError::TS1092 => {
615                "Type parameters cannot appear on a constructor declaration".into()
616            }
617            SyntaxError::TS1096 => "An index signature must have exactly one parameter".into(),
618            SyntaxError::TS1098 => "Type parameter list cannot be empty".into(),
619            SyntaxError::TS1100 => "Invalid use of 'arguments' in strict mode".into(),
620            SyntaxError::TS1102 => {
621                "'delete' cannot be called on an identifier in strict mode".into()
622            }
623            SyntaxError::TS1105 => "A 'break' statement can only be used within an enclosing \
624                                    iteration or switch statement"
625                .into(),
626            SyntaxError::TS1106 => {
627                "The left-hand side of a `for...of` statement may not be `async`".into()
628            }
629            SyntaxError::TS1107 => "Jump target cannot cross function boundary".into(),
630            SyntaxError::TS1109 => "Expression expected".into(),
631            SyntaxError::TS1114 => "Duplicate label".into(),
632            SyntaxError::TS1115 => "A 'continue' statement can only jump to a label of an \
633                                    enclosing iteration statement"
634                .into(),
635            SyntaxError::TS1116 => {
636                "A 'break' statement can only jump to a label of an enclosing statement".into()
637            }
638            SyntaxError::TS1123 => "Variable declaration list cannot be empty".into(),
639            SyntaxError::TS1162 => "An object member cannot be declared optional".into(),
640            SyntaxError::TS1164 => "Computed property names are not allowed in enums".into(),
641            SyntaxError::TS1171 => {
642                "A comma expression is not allowed in a computed property name".into()
643            }
644            SyntaxError::TS1172 => "`extends` clause already seen.".into(),
645            SyntaxError::TS1173 => "'extends' clause must precede 'implements' clause.".into(),
646            SyntaxError::TS1174 => "Classes can only extend a single class".into(),
647            SyntaxError::TS1175 => "`implements` clause already seen".into(),
648            SyntaxError::TS1183 => {
649                "An implementation cannot be declared in ambient contexts".into()
650            }
651            SyntaxError::TS1184 => "Modifiers cannot appear here".into(),
652            SyntaxError::TS1185 => "Merge conflict marker encountered.".into(),
653            SyntaxError::TS1093 => {
654                "Type annotation cannot appear on a constructor declaration".into()
655            }
656            SyntaxError::TS1196 => "Catch clause variable cannot have a type annotation".into(),
657            SyntaxError::TS1242 => {
658                "`abstract` modifier can only appear on a class or method declaration".into()
659            }
660            SyntaxError::TS1244 => {
661                "Abstract methods can only appear within an abstract class.".into()
662            }
663            SyntaxError::TS1243(left, right) => {
664                format!("'{left}' modifier cannot be used with '{right}' modifier.").into()
665            }
666            SyntaxError::TS1245 => "Abstract method cannot have an implementation.".into(),
667            SyntaxError::TS1267 => "Abstract property cannot have an initializer.".into(),
668            SyntaxError::TS1273(word) => {
669                format!("'{word}' modifier cannot appear on a type parameter").into()
670            }
671            SyntaxError::TS1274(word) => format!(
672                "'{word}' modifier can only appear on a type parameter of a class, interface or \
673                 type alias"
674            )
675            .into(),
676            SyntaxError::TS1277(word) => format!(
677                "'{word}' modifier can only appear on a type parameter of a function, method or \
678                 class"
679            )
680            .into(),
681            SyntaxError::TS2206 => "The 'type' modifier cannot be used on a named import when \
682                                    'import type' is used on its import statement."
683                .into(),
684            SyntaxError::TS2207 => "The 'type' modifier cannot be used on a named export when \
685                                    'export type' is used on its export statement."
686                .into(),
687            SyntaxError::TS2369 => {
688                "A parameter property is only allowed in a constructor implementation".into()
689            }
690            SyntaxError::TS2371 => "A parameter initializer is only allowed in a function or \
691                                    constructor implementation"
692                .into(),
693            SyntaxError::TS2406 => "The left-hand side of an assignment expression must be a \
694                                    variable or a property access."
695                .into(),
696            SyntaxError::TS2410 => "The 'with' statement is not supported. All symbols in a \
697                                    'with' block will have type 'any'."
698                .into(),
699            SyntaxError::TS2414 => "Invalid class name".into(),
700            SyntaxError::TS2427 => "interface name is invalid".into(),
701            SyntaxError::TS2452 => "An enum member cannot have a numeric name".into(),
702            SyntaxError::TS2483 => {
703                "The left-hand side of a 'for...of' statement cannot use a type annotation".into()
704            }
705            SyntaxError::TS2491 => "The left-hand side of a 'for...in' statement cannot be a \
706                                    destructuring pattern"
707                .into(),
708            SyntaxError::TS2499 => "An interface can only extend an identifier/qualified-name \
709                                    with optional type arguments."
710                .into(),
711            SyntaxError::TS4112 => "This member cannot have an 'override' modifier because its \
712                                    containing class does not extend another class."
713                .into(),
714            SyntaxError::TS8038 => "Decorators may not appear after `export` or `export default` \
715                                    if they also appear before `export`."
716                .into(),
717            SyntaxError::TS18010 => {
718                "An accessibility modifier cannot be used with a private identifier.".into()
719            }
720            SyntaxError::TSTypeAnnotationAfterAssign => {
721                "Type annotations must come before default assignments".into()
722            }
723            SyntaxError::TsNonNullAssertionNotAllowed(word) => {
724                format!("Typescript non-null assertion operator is not allowed with '{word}'")
725                    .into()
726            }
727            SyntaxError::SetterParamRequired => "Setter should have exactly one parameter".into(),
728            SyntaxError::UnexpectedTokenWithSuggestions {
729                candidate_list: token_list,
730            } => {
731                let did_you_mean = if token_list.len() <= 2 {
732                    token_list.join(" or ")
733                } else {
734                    token_list[0..token_list.len() - 1].join(" , ")
735                        + &*format!("or {}", token_list[token_list.len() - 1])
736                };
737                format!("Unexpected token. Did you mean {did_you_mean}?").into()
738            }
739            SyntaxError::WithLabel { inner, .. } => inner.error.1.msg(),
740            SyntaxError::ReservedTypeAssertion => "This syntax is reserved in files with the .mts \
741                                                   or .cts extension. Use an `as` expression \
742                                                   instead."
743                .into(),
744            SyntaxError::ReservedArrowTypeParam => "This syntax is reserved in files with the \
745                                                    .mts or .cts extension. Add a trailing comma, \
746                                                    as in `<T,>() => ...`."
747                .into(),
748            SyntaxError::InvalidAssignTarget => "Invalid assignment target".into(),
749            SyntaxError::EmptyTypeArgumentList => "Type argument list cannot be empty.".into(),
750        }
751    }
752}
753
754impl Error {
755    #[cold]
756    #[inline(never)]
757    pub fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder {
758        if let SyntaxError::WithLabel { inner, note, span } = self.error.1 {
759            let mut db = inner.into_diagnostic(handler);
760            db.span_label(span, note);
761            return db;
762        }
763
764        let span = self.span();
765
766        let kind = self.into_kind();
767        let msg = kind.msg();
768
769        let mut db = handler.struct_span_err(span, &msg);
770
771        match kind {
772            SyntaxError::ExpectedSemiForExprStmt { expr } => {
773                db.span_label(
774                    expr,
775                    "This is the expression part of an expression statement",
776                );
777            }
778            SyntaxError::MultipleDefault { previous } => {
779                db.span_label(previous, "previous default case is declared at here");
780            }
781            _ => {}
782        }
783
784        db
785    }
786}
787
788#[test]
789fn size_of_error() {
790    assert_eq!(std::mem::size_of::<Error>(), 8);
791}