Skip to content

Commit

Permalink
Remove special-casing for whitespace-around-@
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed May 16, 2023
1 parent d9c3f8e commit 29fd046
Showing 1 changed file with 66 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,83 +71,77 @@ pub(crate) fn missing_whitespace_around_operator(
_ => {}
};

let needs_space = if kind == TokenKind::Equal && parens > 0 {
// Allow keyword args or defaults: foo(bar=None).
NeedsSpace::No
} else if kind == TokenKind::Slash {
// Tolerate the "/" operator in function definition
// For more info see PEP570

// `def f(a, /, b):` or `def f(a, b, /):` or `f = lambda a, /:`
// ^ ^ ^
let slash_in_func = matches!(
tokens.peek().map(|t| t.kind()),
Some(TokenKind::Comma | TokenKind::Rpar | TokenKind::Colon)
);

NeedsSpace::from(!slash_in_func)
} else if kind.is_unary()
|| matches!(
kind,
TokenKind::Star | TokenKind::DoubleStar | TokenKind::At
)
{
let is_binary = prev_token.map_or(false, |prev_token| {
let prev_kind = prev_token.kind();

// Check if the operator is used as a binary operator.
// Allow unary operators: -123, -x, +1.
// Allow argument unpacking: foo(*args, **kwargs)
// Allow decorators: @foo, @foo(1)
matches!(
prev_kind,
TokenKind::Rpar | TokenKind::Rsqb | TokenKind::Rbrace
) || !(prev_kind.is_operator()
|| prev_kind.is_keyword()
|| prev_kind.is_soft_keyword())
});

if is_binary {
if kind == TokenKind::DoubleStar {
// Enforce consistent spacing, but don't enforce whitespaces.
NeedsSpace::Optional
if let Some(prev_token) = prev_token {
let needs_space = if kind == TokenKind::Equal && parens > 0 {
// Allow keyword args or defaults: foo(bar=None).
NeedsSpace::No
} else if kind == TokenKind::Slash {
// Tolerate the "/" operator in function definition
// For more info see PEP570

// `def f(a, /, b):` or `def f(a, b, /):` or `f = lambda a, /:`
// ^ ^ ^
let slash_in_func = matches!(
tokens.peek().map(|t| t.kind()),
Some(TokenKind::Comma | TokenKind::Rpar | TokenKind::Colon)
);

NeedsSpace::from(!slash_in_func)
} else if kind.is_unary() || matches!(kind, TokenKind::Star | TokenKind::DoubleStar) {
let is_binary = {
let prev_kind = prev_token.kind();

// Check if the operator is used as a binary operator.
// Allow unary operators: -123, -x, +1.
// Allow argument unpacking: foo(*args, **kwargs)
matches!(
prev_kind,
TokenKind::Rpar | TokenKind::Rsqb | TokenKind::Rbrace
) || !(prev_kind.is_operator()
|| prev_kind.is_keyword()
|| prev_kind.is_soft_keyword())
};

if is_binary {
if kind == TokenKind::DoubleStar {
// Enforce consistent spacing, but don't enforce whitespaces.
NeedsSpace::Optional
} else {
NeedsSpace::Yes
}
} else {
NeedsSpace::Yes
NeedsSpace::No
}
} else if is_whitespace_needed(kind) {
NeedsSpace::Yes
} else {
NeedsSpace::No
}
} else if is_whitespace_needed(kind) {
NeedsSpace::Yes
} else {
NeedsSpace::No
};

if needs_space != NeedsSpace::No {
let has_leading_trivia = prev_token.map_or(true, |prev| {
prev.end() < token.start() || prev.kind().is_trivia()
});

let has_trailing_trivia = tokens.peek().map_or(true, |next| {
token.end() < next.start() || next.kind().is_trivia()
});

match (has_leading_trivia, has_trailing_trivia) {
// Operator with trailing but no leading space, enforce consistent spacing
(false, true) |
// Operator with leading but no trailing space, enforce consistent spacing.
(true, false)
=> {
context.push(MissingWhitespaceAroundOperator, token.range());
}
// Operator with no space, require spaces if it is required by the operator.
(false, false) => {
if needs_space == NeedsSpace::Yes {
context.push(diagnostic_kind_for_operator(kind), token.range());
};

if needs_space != NeedsSpace::No {
let has_leading_trivia =
prev_token.end() < token.start() || prev_token.kind().is_trivia();

let has_trailing_trivia = tokens.peek().map_or(true, |next| {
token.end() < next.start() || next.kind().is_trivia()
});

match (has_leading_trivia, has_trailing_trivia) {
// Operator with trailing but no leading space, enforce consistent spacing.
(false, true) |
// Operator with leading but no trailing space, enforce consistent spacing.
(true, false) => {
context.push(MissingWhitespaceAroundOperator, token.range());
}
// Operator with no space, require spaces if it is required by the operator.
(false, false) => {
if needs_space == NeedsSpace::Yes {
context.push(diagnostic_kind_for_operator(kind), token.range());
}
}
(true, true) => {
// Operator has leading and trailing spaces, all good.
}
}
(true, true) => {
// Operator has leading and trailing spaces, all good
}
}
}
Expand Down

0 comments on commit 29fd046

Please sign in to comment.