Add duplicate arguments check (#8)

This commit is contained in:
Charlie Marsh 2022-08-13 14:20:19 -04:00 committed by GitHub
parent d5d9dec5ff
commit 290b0091c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 6 deletions

2
Cargo.lock generated
View File

@ -1493,7 +1493,7 @@ dependencies = [
[[package]]
name = "rust-python-linter"
version = "0.0.7"
version = "0.0.8"
dependencies = [
"anyhow",
"bincode",

View File

@ -1,6 +1,6 @@
[package]
name = "rust-python-linter"
version = "0.0.7"
version = "0.0.8"
edition = "2021"
[lib]

View File

@ -1 +1,5 @@
from bar import *
def baz(x: int, x: int) -> None:
pass

View File

@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub enum CheckKind {
DuplicateArgumentName,
ImportStarUsage,
IfTuple,
}
@ -11,16 +12,18 @@ impl CheckKind {
/// A four-letter shorthand code for the check.
pub fn code(&self) -> &'static str {
match self {
CheckKind::ImportStarUsage => "F403",
CheckKind::DuplicateArgumentName => "F831",
CheckKind::IfTuple => "F634",
CheckKind::ImportStarUsage => "F403",
}
}
/// The body text for the check.
pub fn body(&self) -> &'static str {
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::ImportStarUsage => "Unable to detect undefined names",
}
}
}

View File

@ -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::visitor::{walk_stmt, Visitor};
use crate::visitor::{walk_arguments, walk_stmt, Visitor};
struct Checker {
checks: Vec<Check>,
@ -32,6 +34,38 @@ impl Visitor for Checker {
}
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> {