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#[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 InvalidIdentInStrict(Atom),
105
106 InvalidIdentInAsync,
107 EvalAndArgumentsInStrict,
109 ArgumentsInClassField,
110 IllegalLanguageModeDirective,
111 UnaryInExp {
112 left: String,
113 left_span: Span,
114 },
115 Hash,
116 LineBreakInThrow,
117 LineBreakBeforeArrow,
118
119 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 previous: Span,
142 },
143 CommaAfterRestElement,
144 NonLastRestParam,
145 SpreadInParenExpr,
146 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 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}