Skip to content

Commit

Permalink
[red-knot] Allow any Ranged argument for report_lint and `report_…
Browse files Browse the repository at this point in the history
…diagnostic` (#16252)
  • Loading branch information
MichaReiser authored Feb 19, 2025
1 parent 3032867 commit 55ea094
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 220 deletions.
6 changes: 1 addition & 5 deletions crates/red_knot_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2264,11 +2264,7 @@ impl<'db> InvalidTypeExpressionError<'db> {
invalid_expressions,
} = self;
for error in invalid_expressions {
context.report_lint(
&INVALID_TYPE_FORM,
node.into(),
format_args!("{}", error.reason()),
);
context.report_lint(&INVALID_TYPE_FORM, node, format_args!("{}", error.reason()));
}
fallback_type
}
Expand Down
75 changes: 45 additions & 30 deletions crates/red_knot_python_semantic/src/types/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use ruff_db::{
diagnostic::{DiagnosticId, SecondaryDiagnosticMessage, Severity},
files::File,
};
use ruff_python_ast::AnyNodeRef;
use ruff_text_size::Ranged;
use ruff_text_size::{Ranged, TextRange};

use super::{binding_type, KnownFunction, TypeCheckDiagnostic, TypeCheckDiagnostics};

Expand Down Expand Up @@ -67,46 +66,60 @@ impl<'db> InferContext<'db> {
self.diagnostics.get_mut().extend(other.diagnostics());
}

/// Reports a lint located at `node`.
pub(super) fn report_lint(
/// Reports a lint located at `ranged`.
pub(super) fn report_lint<T>(
&self,
lint: &'static LintMetadata,
node: AnyNodeRef,
ranged: T,
message: fmt::Arguments,
) {
self.report_lint_with_secondary_messages(lint, node, message, vec![]);
) where
T: Ranged,
{
self.report_lint_with_secondary_messages(lint, ranged, message, vec![]);
}

/// Reports a lint located at `node`.
pub(super) fn report_lint_with_secondary_messages(
/// Reports a lint located at `ranged`.
pub(super) fn report_lint_with_secondary_messages<T>(
&self,
lint: &'static LintMetadata,
node: AnyNodeRef,
ranged: T,
message: fmt::Arguments,
secondary_messages: Vec<SecondaryDiagnosticMessage>,
) {
if !self.db.is_file_open(self.file) {
return;
}
) where
T: Ranged,
{
fn lint_severity(
context: &InferContext,
lint: &'static LintMetadata,
range: TextRange,
) -> Option<Severity> {
if !context.db.is_file_open(context.file) {
return None;
}

// Skip over diagnostics if the rule is disabled.
let Some(severity) = self.db.rule_selection().severity(LintId::of(lint)) else {
return;
};
// Skip over diagnostics if the rule is disabled.
let severity = context.db.rule_selection().severity(LintId::of(lint))?;

if self.is_in_no_type_check() {
return;
}
if context.is_in_no_type_check() {
return None;
}

let suppressions = suppressions(self.db, self.file);
let suppressions = suppressions(context.db, context.file);

if let Some(suppression) = suppressions.find_suppression(node.range(), LintId::of(lint)) {
self.diagnostics.borrow_mut().mark_used(suppression.id());
return;
if let Some(suppression) = suppressions.find_suppression(range, LintId::of(lint)) {
context.diagnostics.borrow_mut().mark_used(suppression.id());
return None;
}

Some(severity)
}

let Some(severity) = lint_severity(self, lint, ranged.range()) else {
return;
};

self.report_diagnostic(
node,
ranged,
DiagnosticId::Lint(lint.name()),
severity,
message,
Expand All @@ -117,14 +130,16 @@ impl<'db> InferContext<'db> {
/// Adds a new diagnostic.
///
/// The diagnostic does not get added if the rule isn't enabled for this file.
pub(super) fn report_diagnostic(
pub(super) fn report_diagnostic<T>(
&self,
node: AnyNodeRef,
ranged: T,
id: DiagnosticId,
severity: Severity,
message: fmt::Arguments,
secondary_messages: Vec<SecondaryDiagnosticMessage>,
) {
) where
T: Ranged,
{
if !self.db.is_file_open(self.file) {
return;
}
Expand All @@ -139,7 +154,7 @@ impl<'db> InferContext<'db> {
file: self.file,
id,
message: message.to_string(),
range: node.range(),
range: ranged.range(),
severity,
secondary_messages,
});
Expand Down
14 changes: 7 additions & 7 deletions crates/red_knot_python_semantic/src/types/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ pub(super) fn report_possibly_unresolved_reference(

context.report_lint(
&POSSIBLY_UNRESOLVED_REFERENCE,
expr_name_node.into(),
expr_name_node,
format_args!("Name `{id}` used when possibly not defined"),
);
}
Expand All @@ -1057,15 +1057,15 @@ pub(super) fn report_unresolved_reference(context: &InferContext, expr_name_node

context.report_lint(
&UNRESOLVED_REFERENCE,
expr_name_node.into(),
expr_name_node,
format_args!("Name `{id}` used when not defined"),
);
}

pub(super) fn report_invalid_exception_caught(context: &InferContext, node: &ast::Expr, ty: Type) {
context.report_lint(
&INVALID_EXCEPTION_CAUGHT,
node.into(),
node,
format_args!(
"Cannot catch object of type `{}` in an exception handler \
(must be a `BaseException` subclass or a tuple of `BaseException` subclasses)",
Expand All @@ -1077,7 +1077,7 @@ pub(super) fn report_invalid_exception_caught(context: &InferContext, node: &ast
pub(crate) fn report_invalid_exception_raised(context: &InferContext, node: &ast::Expr, ty: Type) {
context.report_lint(
&INVALID_RAISE,
node.into(),
node,
format_args!(
"Cannot raise object of type `{}` (must be a `BaseException` subclass or instance)",
ty.display(context.db())
Expand All @@ -1088,7 +1088,7 @@ pub(crate) fn report_invalid_exception_raised(context: &InferContext, node: &ast
pub(crate) fn report_invalid_exception_cause(context: &InferContext, node: &ast::Expr, ty: Type) {
context.report_lint(
&INVALID_RAISE,
node.into(),
node,
format_args!(
"Cannot use object of type `{}` as exception cause \
(must be a `BaseException` subclass or instance or `None`)",
Expand All @@ -1100,7 +1100,7 @@ pub(crate) fn report_invalid_exception_cause(context: &InferContext, node: &ast:
pub(crate) fn report_base_with_incompatible_slots(context: &InferContext, node: &ast::Expr) {
context.report_lint(
&INCOMPATIBLE_SLOTS,
node.into(),
node,
format_args!("Class base has incompatible `__slots__`"),
);
}
Expand All @@ -1112,7 +1112,7 @@ pub(crate) fn report_invalid_arguments_to_annotated<'db>(
) {
context.report_lint(
&INVALID_TYPE_FORM,
subscript.into(),
subscript,
format_args!(
"Special form `{}` expected at least 2 arguments (one type and at least one metadata element)",
KnownInstanceType::Annotated.repr(db)
Expand Down
Loading

0 comments on commit 55ea094

Please sign in to comment.