rust/crates/ra_syntax/src/yellow/syntax_error.rs

118 lines
3.5 KiB
Rust
Raw Normal View History

use std::fmt;
use crate::{TextRange, TextUnit};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SyntaxError {
kind: SyntaxErrorKind,
location: Location,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Location {
Offset(TextUnit),
Range(TextRange),
}
impl Into<Location> for TextUnit {
fn into(self) -> Location {
Location::Offset(self)
}
}
impl Into<Location> for TextRange {
fn into(self) -> Location {
Location::Range(self)
}
}
impl SyntaxError {
pub fn new<L: Into<Location>>(kind: SyntaxErrorKind, loc: L) -> SyntaxError {
2018-11-05 15:29:33 -06:00
SyntaxError {
kind,
location: loc.into(),
}
}
2018-11-07 04:35:33 -06:00
pub fn kind(&self) -> SyntaxErrorKind {
self.kind.clone()
}
pub fn location(&self) -> Location {
self.location.clone()
}
pub fn offset(&self) -> TextUnit {
match self.location {
Location::Offset(offset) => offset,
Location::Range(range) => range.start(),
}
}
pub fn add_offset(mut self, plus_offset: TextUnit) -> SyntaxError {
self.location = match self.location {
Location::Range(range) => Location::Range(range + plus_offset),
2018-11-05 15:29:33 -06:00
Location::Offset(offset) => Location::Offset(offset + plus_offset),
};
self
}
}
impl fmt::Display for SyntaxError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.kind.fmt(f)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum SyntaxErrorKind {
ParseError(ParseError),
2018-11-07 04:35:33 -06:00
UnescapedCodepoint,
EmptyChar,
UnclosedChar,
2018-11-08 08:42:00 -06:00
OverlongChar,
EmptyAsciiEscape,
InvalidAsciiEscape,
2018-11-06 10:05:06 -06:00
TooShortAsciiCodeEscape,
AsciiCodeEscapeOutOfRange,
MalformedAsciiCodeEscape,
UnclosedUnicodeEscape,
MalformedUnicodeEscape,
EmptyUnicodeEcape,
OverlongUnicodeEscape,
UnicodeEscapeOutOfRange,
2018-11-08 08:42:00 -06:00
UnclosedString,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ParseError(pub String);
impl fmt::Display for SyntaxErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::SyntaxErrorKind::*;
match self {
2018-11-07 04:35:33 -06:00
UnescapedCodepoint => write!(f, "This codepoint should always be escaped"),
EmptyAsciiEscape => write!(f, "Empty escape sequence"),
InvalidAsciiEscape => write!(f, "Invalid escape sequence"),
EmptyChar => write!(f, "Empty char literal"),
UnclosedChar => write!(f, "Unclosed char literal"),
2018-11-08 08:42:00 -06:00
OverlongChar => write!(f, "Char literal should be one character long"),
2018-11-06 10:05:06 -06:00
TooShortAsciiCodeEscape => write!(f, "Escape sequence should have two digits"),
2018-11-07 04:41:42 -06:00
AsciiCodeEscapeOutOfRange => {
write!(f, "Escape sequence should be between \\x00 and \\x7F")
}
2018-11-06 10:05:06 -06:00
MalformedAsciiCodeEscape => write!(f, "Escape sequence should be a hexadecimal number"),
UnclosedUnicodeEscape => write!(f, "Missing `}}`"),
MalformedUnicodeEscape => write!(f, "Malformed unicode escape sequence"),
EmptyUnicodeEcape => write!(f, "Empty unicode escape sequence"),
2018-11-07 04:41:42 -06:00
OverlongUnicodeEscape => {
write!(f, "Unicode escape sequence should have at most 6 digits")
}
2018-11-06 10:05:06 -06:00
UnicodeEscapeOutOfRange => write!(f, "Unicode escape code should be at most 0x10FFFF"),
2018-11-08 08:42:00 -06:00
UnclosedString => write!(f, "Unclosed string literal"),
ParseError(msg) => write!(f, "{}", msg.0),
}
}
}