Introduce StringLike enum (#9016)

## Summary

This PR introduces a new `StringLike` enum which is a narrow type to
indicate string-like nodes. These includes the string literals, bytes
literals, and the literal parts of f-strings.

The main motivation behind this is to avoid repetition of rule calling
in the AST checker. We add a new `analyze::string_like` function which
takes in the enum and calls all the respective rule functions which
expects atleast 2 of the variants of this enum.

I'm open to discarding this if others think it's not that useful at this
stage as currently only 3 rules require these nodes.

As suggested
[here](https://github.com/astral-sh/ruff/pull/8835#discussion_r1414746934)
and
[here](https://github.com/astral-sh/ruff/pull/8835#discussion_r1414750204).

## Test Plan

`cargo test`
This commit is contained in:
Dhruv Manilawala 2023-12-07 10:39:13 -06:00 committed by GitHub
parent cdac90ef68
commit 96ae9fe685
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 108 additions and 72 deletions

View file

@ -393,3 +393,41 @@ impl LiteralExpressionRef<'_> {
}
}
}
/// An enum that holds a reference to a string-like literal from the AST.
/// This includes string literals, bytes literals, and the literal parts of
/// f-strings.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum StringLike<'a> {
StringLiteral(&'a ast::ExprStringLiteral),
BytesLiteral(&'a ast::ExprBytesLiteral),
FStringLiteral(&'a ast::FStringLiteralElement),
}
impl<'a> From<&'a ast::ExprStringLiteral> for StringLike<'a> {
fn from(value: &'a ast::ExprStringLiteral) -> Self {
StringLike::StringLiteral(value)
}
}
impl<'a> From<&'a ast::ExprBytesLiteral> for StringLike<'a> {
fn from(value: &'a ast::ExprBytesLiteral) -> Self {
StringLike::BytesLiteral(value)
}
}
impl<'a> From<&'a ast::FStringLiteralElement> for StringLike<'a> {
fn from(value: &'a ast::FStringLiteralElement) -> Self {
StringLike::FStringLiteral(value)
}
}
impl Ranged for StringLike<'_> {
fn range(&self) -> TextRange {
match self {
StringLike::StringLiteral(literal) => literal.range(),
StringLike::BytesLiteral(literal) => literal.range(),
StringLike::FStringLiteral(literal) => literal.range(),
}
}
}