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