1use std::borrow::Cow;
2
3use swc_atoms::Atom;
4use swc_common::{
5 errors::{DiagnosticBuilder, Handler},
6 Span,
7};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct Error {
12 inner: Box<(Span, ErrorKind)>,
13}
14
15impl Error {
16 pub fn kind(&self) -> &ErrorKind {
17 &self.inner.1
18 }
19
20 pub fn into_inner(self) -> Box<(Span, ErrorKind)> {
21 self.inner
22 }
23
24 pub fn new(span: Span, kind: ErrorKind) -> Self {
25 Error {
26 inner: Box::new((span, kind)),
27 }
28 }
29
30 pub fn message(&self) -> Cow<'static, str> {
31 match &self.inner.1 {
32 ErrorKind::Eof => "Unexpected end of file".into(),
33
34 ErrorKind::InvalidEscape => "An invalid escape".into(),
36 ErrorKind::UnterminatedString => "Unterminated string".into(),
37 ErrorKind::NewlineInString => "Newline in string".into(),
38 ErrorKind::UnterminatedUrl => "Unterminated url".into(),
39 ErrorKind::UnexpectedCharInUrl => "Unexpected character in url".into(),
40
41 ErrorKind::EofButExpected(s) => {
43 format!("Unexpected end of file, but expected {s}").into()
44 }
45 ErrorKind::Ignore => "Not an error".into(),
46 ErrorKind::UnexpectedChar(c) => format!("Unexpected character `{c:?}`").into(),
47 ErrorKind::Expected(s) => format!("Expected {s}").into(),
48 ErrorKind::Unexpected(s) => format!("Unexpected {s}").into(),
49 ErrorKind::ExpectedButGot(s) => format!("Expected {s}").into(),
50 ErrorKind::ExpectedSelectorText => "Expected a text for selector".into(),
51 ErrorKind::UnterminatedBlockComment => "Unterminated block comment".into(),
52 ErrorKind::InvalidCharsetAtRule => "Invalid @charset at-rule".into(),
53 ErrorKind::InvalidTypeSelector => "Invalid type selector".into(),
54 ErrorKind::InvalidSelector => "Invalid selector".into(),
55 ErrorKind::InvalidAttrSelectorName => "Invalid attribute name".into(),
56 ErrorKind::InvalidAttrSelectorMatcher => "Invalid attribute matcher".into(),
57 ErrorKind::InvalidAttrSelectorMatcherValue => "Invalid attribute matcher value".into(),
58 ErrorKind::InvalidAttrSelectorModifier => "Invalid attribute modifier".into(),
59 ErrorKind::ExpectedNumber => "Expected a number".into(),
60 ErrorKind::InvalidSupportQuery => "Invalid support query".into(),
61 ErrorKind::InvalidMediaQuery => "Invalid media query".into(),
62 ErrorKind::InvalidLayerBlockAtRule => "Invalid @layer block at-rule".into(),
63 ErrorKind::UnknownAtRuleNotTerminated => "Unknown @rule is not terminated".into(),
64 ErrorKind::InvalidDeclarationValue => "Expected a property value".into(),
65 ErrorKind::InvalidAnPlusBMicrosyntax => "Invalid An+B microsyntax".into(),
66 ErrorKind::InvalidCustomIdent(s) => {
67 format!("The CSS-wide keywords are not valid custom ident, found '{s}'").into()
68 }
69 ErrorKind::InvalidKeyframesName(s) => {
70 format!("{s} is not valid name for keyframes").into()
71 }
72 ErrorKind::InvalidScopeAtRule => "Invalid @scope at-rule".into(),
73 ErrorKind::ValueAtRule => "@value at-rule is deprecated".into(),
74 }
75 }
76
77 pub fn to_diagnostics<'a>(&self, handler: &'a Handler) -> DiagnosticBuilder<'a> {
78 handler.struct_span_err(self.inner.0, &self.message())
79 }
80}
81
82#[derive(Debug, Clone, PartialEq, Eq)]
83#[non_exhaustive]
84pub enum ErrorKind {
85 Eof,
86
87 InvalidEscape,
89 UnterminatedString,
90 NewlineInString,
91 UnterminatedUrl,
92 UnexpectedCharInUrl,
93
94 Ignore,
96 EofButExpected(&'static str),
97 UnexpectedChar(char),
98 Expected(&'static str),
99 Unexpected(&'static str),
100 ExpectedButGot(&'static str),
101 ExpectedSelectorText,
102 UnterminatedBlockComment,
103 InvalidCharsetAtRule,
104 InvalidTypeSelector,
105 InvalidSelector,
106 InvalidDeclarationValue,
107 InvalidAttrSelectorName,
108 InvalidAttrSelectorMatcher,
109 InvalidAttrSelectorMatcherValue,
110 InvalidAttrSelectorModifier,
111 ExpectedNumber,
112 InvalidSupportQuery,
113 InvalidLayerBlockAtRule,
114 InvalidMediaQuery,
115 InvalidAnPlusBMicrosyntax,
116 InvalidCustomIdent(Atom),
117 InvalidKeyframesName(&'static str),
118 InvalidScopeAtRule,
119
120 UnknownAtRuleNotTerminated,
121
122 ValueAtRule,
123}