1#![allow(dead_code)]
2
3use std::{borrow::Cow, fmt::Debug};
4
5use swc_atoms::Atom;
6use swc_common::{
7 errors::{DiagnosticBuilder, Handler},
8 Span, Spanned,
9};
10
11#[derive(Debug, Clone, PartialEq)]
13pub struct Error {
14 error: Box<(Span, SyntaxError)>,
15}
16
17impl Spanned for Error {
18 fn span(&self) -> Span {
19 (*self.error).0
20 }
21}
22
23impl Error {
24 #[cold]
25 pub fn new(span: Span, error: SyntaxError) -> Self {
26 Self {
27 error: Box::new((span, error)),
28 }
29 }
30
31 pub fn kind(&self) -> &SyntaxError {
32 &self.error.1
33 }
34
35 pub fn into_kind(self) -> SyntaxError {
36 self.error.1
37 }
38}
39
40#[derive(Debug, Clone, PartialEq)]
41#[non_exhaustive]
42pub enum SyntaxError {
43 Eof,
44 DeclNotAllowed,
45
46 UsingDeclNotAllowed,
47 UsingDeclNotAllowedForForInLoop,
48 UsingDeclNotEnabled,
49 InvalidNameInUsingDecl,
50 InitRequiredForUsingDecl,
51
52 PrivateNameInInterface,
53
54 InvalidSuperCall,
55 InvalidSuper,
56 InvalidSuperPrivateName,
57
58 InvalidNewTarget,
59
60 InvalidImport,
61
62 ArrowNotAllowed,
63 ExportNotAllowed,
64 GetterSetterCannotBeReadonly,
65 GetterSetterCannotBeOptional,
66 GetterParam,
67 SetterParam,
68
69 TopLevelAwaitInScript,
70
71 LegacyDecimal,
72 LegacyOctal,
73 InvalidIdentChar,
74 ExpectedDigit {
75 radix: u8,
76 },
77 SetterParamRequired,
78 RestPatInSetter,
79
80 UnterminatedBlockComment,
81 UnterminatedStrLit,
82 ExpectedUnicodeEscape,
83 EscapeInReservedWord {
84 word: Atom,
85 },
86 UnterminatedRegExp,
87 UnterminatedTpl,
88 IdentAfterNum,
89 UnexpectedChar {
90 c: char,
91 },
92 InvalidStrEscape,
93 InvalidUnicodeEscape,
94 BadCharacterEscapeSequence {
95 expected: &'static str,
96 },
97 NumLitTerminatedWithExp,
98 LegacyCommentInModule,
99
100 InvalidIdentInStrict(Atom),
103
104 InvalidIdentInAsync,
105 EvalAndArgumentsInStrict,
107 ArgumentsInClassField,
108 IllegalLanguageModeDirective,
109 UnaryInExp {
110 left: String,
111 left_span: Span,
112 },
113 Hash,
114 LineBreakInThrow,
115 LineBreakBeforeArrow,
116
117 Unexpected {
119 got: String,
120 expected: &'static str,
121 },
122 UnexpectedTokenWithSuggestions {
123 candidate_list: Vec<&'static str>,
124 },
125 ReservedWordInImport,
126 AssignProperty,
127 Expected(String, String),
128 ExpectedSemiForExprStmt {
129 expr: Span,
130 },
131
132 AwaitStar,
133 ReservedWordInObjShorthandOrPat,
134
135 NullishCoalescingWithLogicalOp,
136
137 MultipleDefault {
138 previous: Span,
140 },
141 CommaAfterRestElement,
142 NonLastRestParam,
143 SpreadInParenExpr,
144 EmptyParenExpr,
146 InvalidPat,
147 InvalidExpr,
148 NotSimpleAssign,
149 InvalidAssignTarget,
150 ExpectedIdent,
151 ExpectedSemi,
152 DuplicateLabel(Atom),
153 AsyncGenerator,
154 NonTopLevelImportExport,
155 ImportExportInScript,
156 ImportMetaInScript,
157 PatVarWithoutInit,
158 WithInStrict,
159 ReturnNotAllowed,
160 TooManyVarInForInHead,
161 VarInitializerInForInHead,
162 LabelledGeneratorOrAsync,
163 LabelledFunctionInStrict,
164 YieldParamInGen,
165 AwaitParamInAsync,
166
167 AwaitForStmt,
168
169 AwaitInFunction,
170
171 UnterminatedJSXContents,
172 EmptyJSXAttr,
173 InvalidJSXValue,
174 JSXExpectedClosingTagForLtGt,
175 JSXExpectedClosingTag {
176 tag: Atom,
177 },
178 InvalidLeadingDecorator,
179 DecoratorOnExport,
180
181 TsRequiredAfterOptional,
182 TsInvalidParamPropPat,
183
184 SpaceBetweenHashAndIdent,
185
186 AsyncConstructor,
187 PropertyNamedConstructor,
188 PrivateConstructor,
189 PrivateNameModifier(Atom),
190 ConstructorAccessor,
191 ReadOnlyMethod,
192 GeneratorConstructor,
193 DuplicateConstructor,
194 TsBindingPatCannotBeOptional,
195 SuperCallOptional,
196 OptChainCannotFollowConstructorCall,
197 TaggedTplInOptChain,
198
199 TrailingCommaInsideImport,
200
201 ExportDefaultWithOutFrom,
202 ExportExpectFrom(Atom),
203
204 DotsWithoutIdentifier,
205
206 NumericSeparatorIsAllowedOnlyBetweenTwoDigits,
207
208 ImportBindingIsString(Atom),
209 ExportBindingIsString,
210
211 ConstDeclarationsRequireInitialization,
212
213 DuplicatedRegExpFlags(char),
214 UnknownRegExpFlags,
215
216 TS1003,
217 TS1005,
218 TS1009,
219 TS1014,
220 TS1015,
221 TS1029(Atom, Atom),
222 TS1030(Atom),
223 TS1031,
224 TS1038,
225 TS1042,
226 TS1047,
227 TS1048,
228 TS1056,
229 TS1085,
230 TS1089(Atom),
231 TS1092,
232 TS1096,
233 TS1098,
234 TS1100,
235 TS1102,
236 TS1105,
237 TS1106,
238 TS1107,
239 TS1109,
240 TS1110,
241 TS1114,
242 TS1115,
243 TS1116,
244 TS1123,
245 TS1141,
246 TS1162,
247 TS1164,
248 TS1171,
249 TS1172,
250 TS1173,
251 TS1174,
252 TS1175,
253 TS1183,
254 TS1184,
255 TS1185,
256 TS1093,
257 TS1196,
258 TS1242,
259 TS1243(Atom, Atom),
260 TS1244,
261 TS1245,
262 TS1267,
263 TS1273(Atom),
264 TS1274(Atom),
265 TS1277(Atom),
266 TS2206,
267 TS2207,
268 TS2369,
269 TS2371,
270 TS2406,
271 TS2410,
272 TS2414,
273 TS2427,
274 TS2452,
275 TS2483,
276 TS2491,
277 TS2499,
278 TS2703,
279 TS4112,
280 TS8038,
281 TS18010,
282 TSTypeAnnotationAfterAssign,
283 TsNonNullAssertionNotAllowed(Atom),
284
285 WithLabel {
286 inner: Box<Error>,
287 span: Span,
288 note: &'static str,
289 },
290
291 ReservedTypeAssertion,
292 ReservedArrowTypeParam,
293 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 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}