Skip to content

Commit

Permalink
WIP: ExprStringList
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvmanila committed Oct 19, 2023
1 parent fd9f090 commit 1ae9b42
Show file tree
Hide file tree
Showing 18 changed files with 8,077 additions and 7,730 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -209,5 +209,8 @@ fn is_allowed_value(expr: &Expr) -> bool {
| Expr::Starred(_)
| Expr::Slice(_)
| Expr::IpyEscapeCommand(_) => false,
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
}
}
1 change: 1 addition & 0 deletions crates/ruff_linter/src/rules/ruff/rules/unreachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ impl<'stmt> BasicBlocksBuilder<'stmt> {
| Expr::Yield(_)
| Expr::YieldFrom(_) => self.unconditional_next_block(after),
Expr::IpyEscapeCommand(_) => todo!(),
Expr::StringList(_) => todo!(),
}
}
// The tough branches are done, here is an easy one.
Expand Down
3 changes: 3 additions & 0 deletions crates/ruff_python_ast/src/comparable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,9 @@ impl<'a> From<&'a ast::Expr> for ComparableExpr<'a> {
kind: *kind,
value: value.as_str(),
}),
ast::Expr::StringList(_) => todo!(),
ast::Expr::StringLiteral(_) => todo!(),
ast::Expr::BytesLiteral(_) => todo!(),
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/ruff_python_ast/src/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ impl<'a> From<&'a Expr> for ExpressionRef<'a> {
Expr::Tuple(value) => ExpressionRef::Tuple(value),
Expr::Slice(value) => ExpressionRef::Slice(value),
Expr::IpyEscapeCommand(value) => ExpressionRef::IpyEscapeCommand(value),
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_python_ast/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ pub fn any_over_expr(expr: &Expr, func: &dyn Fn(&Expr) -> bool) -> bool {
| Expr::NoneLiteral(_)
| Expr::EllipsisLiteral(_)
| Expr::IpyEscapeCommand(_) => false,
Expr::StringList(_) => todo!(),
}
}

Expand Down
6 changes: 6 additions & 0 deletions crates/ruff_python_ast/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4341,6 +4341,9 @@ impl From<Expr> for AnyNode {
Expr::Tuple(node) => AnyNode::ExprTuple(node),
Expr::Slice(node) => AnyNode::ExprSlice(node),
Expr::IpyEscapeCommand(node) => AnyNode::ExprIpyEscapeCommand(node),
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
}
}
}
Expand Down Expand Up @@ -6423,6 +6426,9 @@ impl<'a> From<&'a Expr> for AnyNodeRef<'a> {
Expr::Tuple(node) => AnyNodeRef::ExprTuple(node),
Expr::Slice(node) => AnyNodeRef::ExprSlice(node),
Expr::IpyEscapeCommand(node) => AnyNodeRef::ExprIpyEscapeCommand(node),
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
}
}
}
Expand Down
61 changes: 61 additions & 0 deletions crates/ruff_python_ast/src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,8 @@ pub enum Expr {
NoneLiteral(ExprNoneLiteral),
#[is(name = "ellipsis_literal_expr")]
EllipsisLiteral(ExprEllipsisLiteral),
#[is(name = "string_list_expr")]
StringList(ExprStringList),
#[is(name = "attribute_expr")]
Attribute(ExprAttribute),
#[is(name = "subscript_expr")]
Expand Down Expand Up @@ -1120,6 +1122,59 @@ impl Ranged for ExprEllipsisLiteral {
}
}

#[derive(Clone, Debug, PartialEq)]
pub struct ExprStringList {
pub range: TextRange,
pub values: Vec<StringType>,
}

impl From<ExprStringList> for Expr {
fn from(payload: ExprStringList) -> Self {
Expr::StringList(payload)
}
}

impl Ranged for ExprStringList {
fn range(&self) -> TextRange {
self.range
}
}

impl Deref for ExprStringList {
type Target = [StringType];

fn deref(&self) -> &Self::Target {
&self.values
}
}

#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum StringType {
String(ExprStringLiteral),
Bytes(ExprBytesLiteral),
FString(ExprFString),
}

impl Ranged for StringType {
fn range(&self) -> TextRange {
match self {
Self::String(string) => string.range(),
Self::Bytes(bytes) => bytes.range(),
Self::FString(fstring) => fstring.range(),
}
}
}

impl From<StringType> for Expr {
fn from(payload: StringType) -> Self {
match payload {
StringType::String(string) => Expr::StringLiteral(string),
StringType::Bytes(bytes) => Expr::BytesLiteral(bytes),
StringType::FString(fstring) => Expr::FString(fstring),
}
}
}

/// See also [Attribute](https://docs.python.org/3/library/ast.html#ast.Attribute)
#[derive(Clone, Debug, PartialEq)]
pub struct ExprAttribute {
Expand Down Expand Up @@ -3105,6 +3160,7 @@ impl Ranged for crate::Expr {
Expr::BooleanLiteral(node) => node.range(),
Expr::NoneLiteral(node) => node.range(),
Expr::EllipsisLiteral(node) => node.range(),
Self::StringList(node) => node.range(),
Self::Attribute(node) => node.range(),
Self::Subscript(node) => node.range(),
Self::Starred(node) => node.range(),
Expand Down Expand Up @@ -3435,6 +3491,11 @@ impl From<ExprEllipsisLiteral> for ParenthesizedExpr {
Expr::EllipsisLiteral(payload).into()
}
}
impl From<ExprStringList> for ParenthesizedExpr {
fn from(payload: ExprStringList) -> Self {
Expr::StringList(payload).into()
}
}
impl From<ExprAttribute> for ParenthesizedExpr {
fn from(payload: ExprAttribute) -> Self {
Expr::Attribute(payload).into()
Expand Down
3 changes: 3 additions & 0 deletions crates/ruff_python_ast/src/relocate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,5 +217,8 @@ pub fn relocate_expr(expr: &mut Expr, location: TextRange) {
Expr::IpyEscapeCommand(nodes::ExprIpyEscapeCommand { range, .. }) => {
*range = location;
}
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
}
}
3 changes: 3 additions & 0 deletions crates/ruff_python_ast/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,9 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) {
}
}
Expr::IpyEscapeCommand(_) => {}
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
}
}

Expand Down
3 changes: 3 additions & 0 deletions crates/ruff_python_ast/src/visitor/preorder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ where
Expr::Tuple(expr) => expr.visit_preorder(visitor),
Expr::Slice(expr) => expr.visit_preorder(visitor),
Expr::IpyEscapeCommand(expr) => expr.visit_preorder(visitor),
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
}
}

Expand Down
3 changes: 3 additions & 0 deletions crates/ruff_python_codegen/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,9 @@ impl<'a> Generator<'a> {
Expr::IpyEscapeCommand(ast::ExprIpyEscapeCommand { kind, value, .. }) => {
self.p(&format!("{kind}{value}"));
}
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
}
}

Expand Down
9 changes: 9 additions & 0 deletions crates/ruff_python_formatter/src/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ impl FormatRule<Expr, PyFormatContext<'_>> for FormatExpr {
Expr::Tuple(expr) => expr.format().fmt(f),
Expr::Slice(expr) => expr.format().fmt(f),
Expr::IpyEscapeCommand(expr) => expr.format().fmt(f),
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
});
let parenthesize = match parentheses {
Parentheses::Preserve => is_expression_parenthesized(
Expand Down Expand Up @@ -495,6 +498,9 @@ impl NeedsParentheses for Expr {
Expr::Tuple(expr) => expr.needs_parentheses(parent, context),
Expr::Slice(expr) => expr.needs_parentheses(parent, context),
Expr::IpyEscapeCommand(_) => todo!(),
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
}
}
}
Expand Down Expand Up @@ -724,6 +730,9 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> {
| Expr::Name(_)
| Expr::Slice(_) => {}
Expr::IpyEscapeCommand(_) => todo!(),
Expr::StringList(_) => todo!(),
Expr::StringLiteral(_) => todo!(),
Expr::BytesLiteral(_) => todo!(),
};

walk_expr(self, expr);
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_python_parser/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use crate::{
Mode,
};

mod cursor;
pub(crate) mod cursor;
mod fstring;
mod indentation;

Expand Down
30 changes: 15 additions & 15 deletions crates/ruff_python_parser/src/lexer/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::str::Chars;
pub(crate) const EOF_CHAR: char = '\0';

#[derive(Clone, Debug)]
pub(super) struct Cursor<'a> {
pub(crate) struct Cursor<'a> {
chars: Chars<'a>,
source_length: TextSize,
#[cfg(debug_assertions)]
Expand All @@ -23,49 +23,49 @@ impl<'a> Cursor<'a> {

/// Returns the previous token. Useful for debug assertions.
#[cfg(debug_assertions)]
pub(super) const fn previous(&self) -> char {
pub(crate) const fn previous(&self) -> char {
self.prev_char
}

/// Peeks the next character from the input stream without consuming it.
/// Returns [`EOF_CHAR`] if the file is at the end of the file.
pub(super) fn first(&self) -> char {
pub(crate) fn first(&self) -> char {
self.chars.clone().next().unwrap_or(EOF_CHAR)
}

/// Peeks the second character from the input stream without consuming it.
/// Returns [`EOF_CHAR`] if the position is past the end of the file.
pub(super) fn second(&self) -> char {
pub(crate) fn second(&self) -> char {
let mut chars = self.chars.clone();
chars.next();
chars.next().unwrap_or(EOF_CHAR)
}

/// Returns the remaining text to lex.
pub(super) fn rest(&self) -> &'a str {
pub(crate) fn rest(&self) -> &'a str {
self.chars.as_str()
}

// SAFETY: The `source.text_len` call in `new` would panic if the string length is larger than a `u32`.
#[allow(clippy::cast_possible_truncation)]
pub(super) fn text_len(&self) -> TextSize {
pub(crate) fn text_len(&self) -> TextSize {
TextSize::new(self.chars.as_str().len() as u32)
}

pub(super) fn token_len(&self) -> TextSize {
pub(crate) fn token_len(&self) -> TextSize {
self.source_length - self.text_len()
}

pub(super) fn start_token(&mut self) {
pub(crate) fn start_token(&mut self) {
self.source_length = self.text_len();
}

pub(super) fn is_eof(&self) -> bool {
pub(crate) fn is_eof(&self) -> bool {
self.chars.as_str().is_empty()
}

/// Consumes the next character
pub(super) fn bump(&mut self) -> Option<char> {
pub(crate) fn bump(&mut self) -> Option<char> {
let prev = self.chars.next()?;

#[cfg(debug_assertions)]
Expand All @@ -76,7 +76,7 @@ impl<'a> Cursor<'a> {
Some(prev)
}

pub(super) fn eat_char(&mut self, c: char) -> bool {
pub(crate) fn eat_char(&mut self, c: char) -> bool {
if self.first() == c {
self.bump();
true
Expand All @@ -85,7 +85,7 @@ impl<'a> Cursor<'a> {
}
}

pub(super) fn eat_char2(&mut self, c1: char, c2: char) -> bool {
pub(crate) fn eat_char2(&mut self, c1: char, c2: char) -> bool {
let mut chars = self.chars.clone();
if chars.next() == Some(c1) && chars.next() == Some(c2) {
self.bump();
Expand All @@ -96,7 +96,7 @@ impl<'a> Cursor<'a> {
}
}

pub(super) fn eat_char3(&mut self, c1: char, c2: char, c3: char) -> bool {
pub(crate) fn eat_char3(&mut self, c1: char, c2: char, c3: char) -> bool {
let mut chars = self.chars.clone();
if chars.next() == Some(c1) && chars.next() == Some(c2) && chars.next() == Some(c3) {
self.bump();
Expand All @@ -108,7 +108,7 @@ impl<'a> Cursor<'a> {
}
}

pub(super) fn eat_if<F>(&mut self, mut predicate: F) -> Option<char>
pub(crate) fn eat_if<F>(&mut self, mut predicate: F) -> Option<char>
where
F: FnMut(char) -> bool,
{
Expand All @@ -120,7 +120,7 @@ impl<'a> Cursor<'a> {
}

/// Eats symbols while predicate returns true or until the end of file is reached.
pub(super) fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) {
pub(crate) fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) {
// It was tried making optimized version of this for eg. line comments, but
// LLVM can inline all of this and compile it down to fast iteration over bytes.
while predicate(self.first()) && !self.is_eof() {
Expand Down
Loading

0 comments on commit 1ae9b42

Please sign in to comment.