mirror of https://github.com/astral-sh/ruff
Add duplicate arguments check (#8)
This commit is contained in:
parent
d5d9dec5ff
commit
290b0091c5
|
|
@ -1493,7 +1493,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-python-linter"
|
name = "rust-python-linter"
|
||||||
version = "0.0.7"
|
version = "0.0.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rust-python-linter"
|
name = "rust-python-linter"
|
||||||
version = "0.0.7"
|
version = "0.0.8"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|
|
||||||
|
|
@ -1 +1,5 @@
|
||||||
from bar import *
|
from bar import *
|
||||||
|
|
||||||
|
|
||||||
|
def baz(x: int, x: int) -> None:
|
||||||
|
pass
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub enum CheckKind {
|
pub enum CheckKind {
|
||||||
|
DuplicateArgumentName,
|
||||||
ImportStarUsage,
|
ImportStarUsage,
|
||||||
IfTuple,
|
IfTuple,
|
||||||
}
|
}
|
||||||
|
|
@ -11,16 +12,18 @@ impl CheckKind {
|
||||||
/// A four-letter shorthand code for the check.
|
/// A four-letter shorthand code for the check.
|
||||||
pub fn code(&self) -> &'static str {
|
pub fn code(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
CheckKind::ImportStarUsage => "F403",
|
CheckKind::DuplicateArgumentName => "F831",
|
||||||
CheckKind::IfTuple => "F634",
|
CheckKind::IfTuple => "F634",
|
||||||
|
CheckKind::ImportStarUsage => "F403",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The body text for the check.
|
/// The body text for the check.
|
||||||
pub fn body(&self) -> &'static str {
|
pub fn body(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
CheckKind::ImportStarUsage => "Unable to detect undefined names",
|
CheckKind::DuplicateArgumentName => "Duplicate argument name in function definition",
|
||||||
CheckKind::IfTuple => "If test is a tuple, which is always `True`",
|
CheckKind::IfTuple => "If test is a tuple, which is always `True`",
|
||||||
|
CheckKind::ImportStarUsage => "Unable to detect undefined names",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
use rustpython_parser::ast::{ExprKind, Stmt, StmtKind, Suite};
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use rustpython_parser::ast::{Arg, Arguments, ExprKind, Stmt, StmtKind, Suite};
|
||||||
|
|
||||||
use crate::check::{Check, CheckKind};
|
use crate::check::{Check, CheckKind};
|
||||||
use crate::visitor::{walk_stmt, Visitor};
|
use crate::visitor::{walk_arguments, walk_stmt, Visitor};
|
||||||
|
|
||||||
struct Checker {
|
struct Checker {
|
||||||
checks: Vec<Check>,
|
checks: Vec<Check>,
|
||||||
|
|
@ -32,6 +34,38 @@ impl Visitor for Checker {
|
||||||
}
|
}
|
||||||
walk_stmt(self, stmt);
|
walk_stmt(self, stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_arguments(&mut self, arguments: &Arguments) {
|
||||||
|
// Collect all the arguments into a single vector.
|
||||||
|
let mut all_arguments: Vec<&Arg> = arguments
|
||||||
|
.posonlyargs
|
||||||
|
.iter()
|
||||||
|
.chain(arguments.kwonlyargs.iter())
|
||||||
|
.chain(arguments.args.iter())
|
||||||
|
.collect();
|
||||||
|
if let Some(arg) = &arguments.vararg {
|
||||||
|
all_arguments.push(arg);
|
||||||
|
}
|
||||||
|
if let Some(arg) = &arguments.kwarg {
|
||||||
|
all_arguments.push(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for duplicates.
|
||||||
|
let mut idents: HashSet<String> = HashSet::new();
|
||||||
|
for arg in all_arguments {
|
||||||
|
let ident = &arg.node.arg;
|
||||||
|
if idents.contains(ident) {
|
||||||
|
self.checks.push(Check {
|
||||||
|
kind: CheckKind::DuplicateArgumentName,
|
||||||
|
location: arg.location,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idents.insert(ident.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
walk_arguments(self, arguments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_ast(python_ast: &Suite) -> Vec<Check> {
|
pub fn check_ast(python_ast: &Suite) -> Vec<Check> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue