mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 12:29:28 +00:00
Improve API exposed on ExprStringLiteral
nodes (#16192)
## Summary This PR makes the following changes: - It adjusts various callsites to use the new `ast::StringLiteral::contents_range()` method that was introduced in https://github.com/astral-sh/ruff/pull/16183. This is less verbose and more type-safe than using the `ast::str::raw_contents()` helper function. - It adds a new `ast::ExprStringLiteral::as_unconcatenated_literal()` helper method, and adjusts various callsites to use it. This addresses @MichaReiser's review comment at https://github.com/astral-sh/ruff/pull/16183#discussion_r1957334365. There is no functional change here, but it helps readability to make it clearer that we're differentiating between implicitly concatenated strings and unconcatenated strings at various points. - It renames the `StringLiteralValue::flags()` method to `StringLiteralFlags::first_literal_flags()`. If you're dealing with an implicitly concatenated string `string_node`, `string_node.value.flags().closer_len()` could give an incorrect result; this renaming makes it clearer that the `StringLiteralFlags` instance returned by the method is only guaranteed to give accurate information for the first `StringLiteral` contained in the `ExprStringLiteral` node. - It deletes the unused `BytesLiteralValue::flags()` method. This seems prone to misuse in the same way as `StringLiteralValue::flags()`: if it's an implicitly concatenated bytestring, the `BytesLiteralFlags` instance returned by the method would only give accurate information for the first `BytesLiteral` in the bytestring. ## Test Plan `cargo test`
This commit is contained in:
parent
21999b3be7
commit
b6b1947010
8 changed files with 37 additions and 43 deletions
|
@ -1287,6 +1287,17 @@ pub struct ExprStringLiteral {
|
|||
pub value: StringLiteralValue,
|
||||
}
|
||||
|
||||
impl ExprStringLiteral {
|
||||
/// Return `Some(literal)` if the string only consists of a single `StringLiteral` part
|
||||
/// (indicating that it is not implicitly concatenated). Otherwise, return `None`.
|
||||
pub fn as_unconcatenated_literal(&self) -> Option<&StringLiteral> {
|
||||
match &self.value.inner {
|
||||
StringLiteralValueInner::Single(value) => Some(value),
|
||||
StringLiteralValueInner::Concatenated(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The value representing a [`ExprStringLiteral`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct StringLiteralValue {
|
||||
|
@ -1304,7 +1315,7 @@ impl StringLiteralValue {
|
|||
/// Returns the [`StringLiteralFlags`] associated with this string literal.
|
||||
///
|
||||
/// For an implicitly concatenated string, it returns the flags for the first literal.
|
||||
pub fn flags(&self) -> StringLiteralFlags {
|
||||
pub fn first_literal_flags(&self) -> StringLiteralFlags {
|
||||
self.iter()
|
||||
.next()
|
||||
.expect(
|
||||
|
@ -1485,8 +1496,8 @@ bitflags! {
|
|||
///
|
||||
/// If you're using a `Generator` from the `ruff_python_codegen` crate to generate a lint-rule fix
|
||||
/// from an existing string literal, consider passing along the [`StringLiteral::flags`] field or
|
||||
/// the result of the [`StringLiteralValue::flags`] method. If you don't have an existing string but
|
||||
/// have a `Checker` from the `ruff_linter` crate available, consider using
|
||||
/// the result of the [`StringLiteralValue::first_literal_flags`] method. If you don't have an
|
||||
/// existing string but have a `Checker` from the `ruff_linter` crate available, consider using
|
||||
/// `Checker::default_string_flags` to create instances of this struct; this method will properly
|
||||
/// handle surrounding f-strings. For usage that doesn't fit into one of these categories, the
|
||||
/// public constructor [`StringLiteralFlags::empty`] can be used.
|
||||
|
@ -1791,16 +1802,6 @@ impl BytesLiteralValue {
|
|||
pub fn bytes(&self) -> impl Iterator<Item = u8> + '_ {
|
||||
self.iter().flat_map(|part| part.as_slice().iter().copied())
|
||||
}
|
||||
|
||||
/// Returns the [`BytesLiteralFlags`] associated with this literal.
|
||||
///
|
||||
/// For an implicitly concatenated literal, it returns the flags for the first literal.
|
||||
pub fn flags(&self) -> BytesLiteralFlags {
|
||||
self.iter()
|
||||
.next()
|
||||
.expect("There should always be at least one literal in an `ExprBytesLiteral` node")
|
||||
.flags
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a BytesLiteralValue {
|
||||
|
@ -1890,12 +1891,11 @@ bitflags! {
|
|||
/// ## Notes on usage
|
||||
///
|
||||
/// If you're using a `Generator` from the `ruff_python_codegen` crate to generate a lint-rule fix
|
||||
/// from an existing bytes literal, consider passing along the [`BytesLiteral::flags`] field or the
|
||||
/// result of the [`BytesLiteralValue::flags`] method. If you don't have an existing literal but
|
||||
/// have a `Checker` from the `ruff_linter` crate available, consider using
|
||||
/// `Checker::default_bytes_flags` to create instances of this struct; this method will properly
|
||||
/// handle surrounding f-strings. For usage that doesn't fit into one of these categories, the
|
||||
/// public constructor [`BytesLiteralFlags::empty`] can be used.
|
||||
/// from an existing bytes literal, consider passing along the [`BytesLiteral::flags`] field. If
|
||||
/// you don't have an existing literal but have a `Checker` from the `ruff_linter` crate available,
|
||||
/// consider using `Checker::default_bytes_flags` to create instances of this struct; this method
|
||||
/// will properly handle surrounding f-strings. For usage that doesn't fit into one of these
|
||||
/// categories, the public constructor [`BytesLiteralFlags::empty`] can be used.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct BytesLiteralFlags(BytesLiteralFlagsInner);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue