mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
[red-knot] Display raw characters for string literal (#14351)
## Summary Closes: #14330 | `main` | PR | |--------|--------| | <img width="693" alt="Screenshot 2024-11-15 at 9 41 09 AM" src="https://github.com/user-attachments/assets/0d10f2be-2155-4387-8d39-eb1b5027cfd4"> | <img width="800" alt="Screenshot 2024-11-15 at 9 40 27 AM" src="https://github.com/user-attachments/assets/ba68911c-f4bf-405a-a597-44207b4bde7a"> | ## Test Plan Add test cases for escape and quote characters.
This commit is contained in:
parent
375cead202
commit
874da9c400
1 changed files with 56 additions and 6 deletions
|
@ -1,13 +1,14 @@
|
||||||
//! Display implementations for types.
|
//! Display implementations for types.
|
||||||
|
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter, Write};
|
||||||
|
|
||||||
use ruff_db::display::FormatterJoinExtension;
|
use ruff_db::display::FormatterJoinExtension;
|
||||||
use ruff_python_ast::str::Quote;
|
use ruff_python_ast::str::Quote;
|
||||||
use ruff_python_literal::escape::AsciiEscape;
|
use ruff_python_literal::escape::AsciiEscape;
|
||||||
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
ClassLiteralType, InstanceType, IntersectionType, KnownClass, SubclassOfType, Type, UnionType,
|
ClassLiteralType, InstanceType, IntersectionType, KnownClass, StringLiteralType,
|
||||||
|
SubclassOfType, Type, UnionType,
|
||||||
};
|
};
|
||||||
use crate::Db;
|
use crate::Db;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
@ -91,9 +92,7 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
Type::Intersection(intersection) => intersection.display(self.db).fmt(f),
|
Type::Intersection(intersection) => intersection.display(self.db).fmt(f),
|
||||||
Type::IntLiteral(n) => n.fmt(f),
|
Type::IntLiteral(n) => n.fmt(f),
|
||||||
Type::BooleanLiteral(boolean) => f.write_str(if boolean { "True" } else { "False" }),
|
Type::BooleanLiteral(boolean) => f.write_str(if boolean { "True" } else { "False" }),
|
||||||
Type::StringLiteral(string) => {
|
Type::StringLiteral(string) => string.display(self.db).fmt(f),
|
||||||
write!(f, r#""{}""#, string.value(self.db).replace('"', r#"\""#))
|
|
||||||
}
|
|
||||||
Type::LiteralString => f.write_str("LiteralString"),
|
Type::LiteralString => f.write_str("LiteralString"),
|
||||||
Type::BytesLiteral(bytes) => {
|
Type::BytesLiteral(bytes) => {
|
||||||
let escape =
|
let escape =
|
||||||
|
@ -328,13 +327,40 @@ impl<'db> Display for DisplayTypeArray<'_, 'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'db> StringLiteralType<'db> {
|
||||||
|
fn display(&'db self, db: &'db dyn Db) -> DisplayStringLiteralType<'db> {
|
||||||
|
DisplayStringLiteralType { db, ty: self }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DisplayStringLiteralType<'db> {
|
||||||
|
ty: &'db StringLiteralType<'db>,
|
||||||
|
db: &'db dyn Db,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for DisplayStringLiteralType<'_> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
let value = self.ty.value(self.db);
|
||||||
|
f.write_char('"')?;
|
||||||
|
for ch in value.chars() {
|
||||||
|
match ch {
|
||||||
|
// `escape_debug` will escape even single quotes, which is not necessary for our
|
||||||
|
// use case as we are already using double quotes to wrap the string.
|
||||||
|
'\'' => f.write_char('\'')?,
|
||||||
|
_ => write!(f, "{}", ch.escape_debug())?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.write_char('"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ruff_db::files::system_path_to_file;
|
use ruff_db::files::system_path_to_file;
|
||||||
use ruff_db::system::{DbWithTestSystem, SystemPathBuf};
|
use ruff_db::system::{DbWithTestSystem, SystemPathBuf};
|
||||||
|
|
||||||
use crate::db::tests::TestDb;
|
use crate::db::tests::TestDb;
|
||||||
use crate::types::{global_symbol, SliceLiteralType, Type, UnionType};
|
use crate::types::{global_symbol, SliceLiteralType, StringLiteralType, Type, UnionType};
|
||||||
use crate::{Program, ProgramSettings, PythonVersion, SearchPathSettings};
|
use crate::{Program, ProgramSettings, PythonVersion, SearchPathSettings};
|
||||||
|
|
||||||
fn setup_db() -> TestDb {
|
fn setup_db() -> TestDb {
|
||||||
|
@ -451,4 +477,28 @@ mod tests {
|
||||||
"slice[None, None, Literal[2]]"
|
"slice[None, None, Literal[2]]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn string_literal_display() {
|
||||||
|
let db = setup_db();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Type::StringLiteral(StringLiteralType::new(&db, r"\n"))
|
||||||
|
.display(&db)
|
||||||
|
.to_string(),
|
||||||
|
r#"Literal["\\n"]"#
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Type::StringLiteral(StringLiteralType::new(&db, "'"))
|
||||||
|
.display(&db)
|
||||||
|
.to_string(),
|
||||||
|
r#"Literal["'"]"#
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Type::StringLiteral(StringLiteralType::new(&db, r#"""#))
|
||||||
|
.display(&db)
|
||||||
|
.to_string(),
|
||||||
|
r#"Literal["\""]"#
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue