Skip to content

Commit fe1853b

Browse files
committed
Move helper functions to a separate Module
1 parent a3b7171 commit fe1853b

File tree

3 files changed

+111
-75
lines changed

3 files changed

+111
-75
lines changed

crates/bevy_lint/src/bevy_helpers.rs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use if_chain::if_chain;
2+
use rustc_hir::{
3+
def::Res, hir_id::HirId, intravisit::FnKind, Body, GenericArg, MutTy, Path, QPath, Ty, TyKind,
4+
};
5+
use rustc_lint::LateContext;
6+
use rustc_span::{def_id::DefId, symbol::Symbol, Span};
7+
8+
use crate::bevy_paths;
9+
10+
pub fn path_matches_symbol_path<'hir>(
11+
ctx: &LateContext<'hir>,
12+
path: &Path,
13+
symbol_path: &[&str],
14+
) -> bool {
15+
if let Res::Def(_, def_id) = path.res {
16+
return ctx.match_def_path(
17+
def_id,
18+
symbol_path
19+
.iter()
20+
.map(|str| Symbol::intern(str))
21+
.collect::<Vec<_>>()
22+
.as_slice(),
23+
);
24+
};
25+
26+
false
27+
}
28+
29+
pub fn get_def_id_of_referenced_type(reference: &MutTy) -> Option<DefId> {
30+
if let TyKind::Path(QPath::Resolved(_, path)) = reference.ty.kind {
31+
if let Res::Def(_, def_id) = path.res {
32+
return Some(def_id);
33+
}
34+
}
35+
36+
None
37+
}
38+
39+
pub fn get_def_id_of_first_generic_arg(path: &Path) -> Option<DefId> {
40+
if let Some(segment) = path.segments.iter().last() {
41+
if let Some(generic_args) = segment.args {
42+
if let Some(GenericArg::Type(component)) = &generic_args.args.get(0) {
43+
if let TyKind::Path(QPath::Resolved(_, path)) = component.kind {
44+
if let Res::Def(_, def_id) = path.res {
45+
return Some(def_id);
46+
}
47+
}
48+
}
49+
}
50+
}
51+
52+
None
53+
}
54+
55+
pub fn get_generics_of_query<'hir>(
56+
ctx: &LateContext<'hir>,
57+
query: &'hir Ty,
58+
) -> Option<(&'hir Ty<'hir>, Option<&'hir Ty<'hir>>)> {
59+
if let TyKind::Path(QPath::Resolved(_, path)) = query.kind {
60+
if path_matches_symbol_path(ctx, path, bevy_paths::QUERY) {
61+
if let Some(segment) = path.segments.iter().last() {
62+
if let Some(generic_args) = segment.args {
63+
if let Some(GenericArg::Type(world)) = &generic_args.args.get(1) {
64+
if let Some(GenericArg::Type(filter)) = &generic_args.args.get(2) {
65+
return Some((world, Some(filter)));
66+
}
67+
68+
return Some((world, None));
69+
}
70+
}
71+
}
72+
}
73+
}
74+
75+
None
76+
}

crates/bevy_lint/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern crate rustc_target;
2424
extern crate rustc_trait_selection;
2525
extern crate rustc_typeck;
2626

27+
mod bevy_helpers;
2728
mod bevy_paths;
2829
mod unnecessary_with;
2930

crates/bevy_lint/src/unnecessary_with.rs

+34-75
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
use clippy_utils::diagnostics::span_lint;
2-
use if_chain::if_chain;
32
use rustc_hir::{
4-
def::Res, hir_id::HirId, intravisit::FnKind, Body, FnDecl, GenericArg, MutTy, Path, QPath, Ty,
5-
TyKind,
3+
hir_id::HirId, intravisit::FnKind, Body, FnDecl, GenericArg, Path, QPath, Ty, TyKind,
64
};
75
use rustc_lint::{LateContext, LateLintPass};
86
use rustc_session::{declare_lint, declare_lint_pass};
9-
use rustc_span::{def_id::DefId, symbol::Symbol, Span};
7+
use rustc_span::{def_id::DefId, Span};
108

11-
use crate::bevy_paths;
9+
use crate::{bevy_helpers, bevy_paths};
1210

1311
declare_lint! {
1412
/// **What it does:**
@@ -51,15 +49,13 @@ impl<'hir> LateLintPass<'hir> for UnnecessaryWith {
5149
_: HirId,
5250
) {
5351
for typ in decl.inputs {
54-
if_chain! {
55-
if let TyKind::Path(QPath::Resolved(_, path)) = &typ.kind;
56-
if path_matches_symbol_path(ctx, path, bevy_paths::QUERY);
57-
if let Some(segment) = path.segments.iter().last();
58-
if let Some(generic_args) = segment.args;
59-
if let Some(GenericArg::Type(world)) = &generic_args.args.get(1);
60-
if let Some(GenericArg::Type(filter)) = &generic_args.args.get(2);
61-
then {
62-
check_for_overlap(ctx, world, filter);
52+
if let TyKind::Path(QPath::Resolved(_, path)) = &typ.kind {
53+
if bevy_helpers::path_matches_symbol_path(ctx, path, bevy_paths::QUERY) {
54+
if let Some((world, Some(filter))) =
55+
bevy_helpers::get_generics_of_query(ctx, &typ)
56+
{
57+
check_for_overlap(ctx, world, filter);
58+
}
6359
}
6460
}
6561
}
@@ -72,14 +68,14 @@ fn check_for_overlap<'hir>(ctx: &LateContext<'hir>, world: &Ty, filter: &Ty) {
7268

7369
match &world.kind {
7470
TyKind::Rptr(_, mut_type) => {
75-
if let Some(def_id) = get_def_id_of_reference(&mut_type) {
71+
if let Some(def_id) = bevy_helpers::get_def_id_of_referenced_type(&mut_type) {
7672
required_types.push(def_id);
7773
}
7874
}
7975
TyKind::Tup(types) => {
8076
for typ in *types {
8177
if let TyKind::Rptr(_, mut_type) = &typ.kind {
82-
if let Some(def_id) = get_def_id_of_reference(&mut_type) {
78+
if let Some(def_id) = bevy_helpers::get_def_id_of_referenced_type(&mut_type) {
8379
required_types.push(def_id);
8480
}
8581
}
@@ -90,30 +86,30 @@ fn check_for_overlap<'hir>(ctx: &LateContext<'hir>, world: &Ty, filter: &Ty) {
9086

9187
match &filter.kind {
9288
TyKind::Path(QPath::Resolved(_, path)) => {
93-
if path_matches_symbol_path(ctx, path, bevy_paths::OR) {
89+
if bevy_helpers::path_matches_symbol_path(ctx, path, bevy_paths::OR) {
9490
with_types.extend(check_or_filter(ctx, path));
9591
}
96-
if path_matches_symbol_path(ctx, path, bevy_paths::WITH) {
97-
if let Some(def_id) = get_def_id_of_first_generic_arg(path) {
92+
if bevy_helpers::path_matches_symbol_path(ctx, path, bevy_paths::WITH) {
93+
if let Some(def_id) = bevy_helpers::get_def_id_of_first_generic_arg(path) {
9894
with_types.push((def_id, filter.span));
9995
}
10096
}
10197
}
10298
TyKind::Tup(types) => {
10399
for typ in *types {
104100
if let TyKind::Path(QPath::Resolved(_, path)) = typ.kind {
105-
if path_matches_symbol_path(ctx, path, bevy_paths::OR) {
101+
if bevy_helpers::path_matches_symbol_path(ctx, path, bevy_paths::OR) {
106102
with_types.extend(check_or_filter(ctx, path));
107103
}
108-
if path_matches_symbol_path(ctx, path, bevy_paths::ADDED)
109-
|| path_matches_symbol_path(ctx, path, bevy_paths::CHANGED)
104+
if bevy_helpers::path_matches_symbol_path(ctx, path, bevy_paths::ADDED)
105+
|| bevy_helpers::path_matches_symbol_path(ctx, path, bevy_paths::CHANGED)
110106
{
111-
if let Some(def_id) = get_def_id_of_first_generic_arg(path) {
107+
if let Some(def_id) = bevy_helpers::get_def_id_of_first_generic_arg(path) {
112108
required_types.push(def_id);
113109
}
114110
}
115-
if path_matches_symbol_path(ctx, path, bevy_paths::WITH) {
116-
if let Some(def_id) = get_def_id_of_first_generic_arg(path) {
111+
if bevy_helpers::path_matches_symbol_path(ctx, path, bevy_paths::WITH) {
112+
if let Some(def_id) = bevy_helpers::get_def_id_of_first_generic_arg(path) {
117113
with_types.push((def_id, typ.span));
118114
}
119115
}
@@ -135,51 +131,6 @@ fn check_for_overlap<'hir>(ctx: &LateContext<'hir>, world: &Ty, filter: &Ty) {
135131
}
136132
}
137133

138-
fn get_def_id_of_reference(reference: &MutTy) -> Option<DefId> {
139-
if let TyKind::Path(QPath::Resolved(_, path)) = reference.ty.kind {
140-
if let Res::Def(_, def_id) = path.res {
141-
return Some(def_id);
142-
}
143-
}
144-
145-
None
146-
}
147-
148-
fn path_matches_symbol_path<'hir>(
149-
ctx: &LateContext<'hir>,
150-
path: &Path,
151-
symbol_path: &[&str],
152-
) -> bool {
153-
if let Res::Def(_, def_id) = path.res {
154-
return ctx.match_def_path(
155-
def_id,
156-
symbol_path
157-
.iter()
158-
.map(|str| Symbol::intern(str))
159-
.collect::<Vec<_>>()
160-
.as_slice(),
161-
);
162-
};
163-
164-
false
165-
}
166-
167-
fn get_def_id_of_first_generic_arg(path: &Path) -> Option<DefId> {
168-
if let Some(segment) = path.segments.iter().last() {
169-
if let Some(generic_args) = segment.args {
170-
if let Some(GenericArg::Type(component)) = &generic_args.args.get(0) {
171-
if let TyKind::Path(QPath::Resolved(_, path)) = component.kind {
172-
if let Res::Def(_, def_id) = path.res {
173-
return Some(def_id);
174-
}
175-
}
176-
}
177-
}
178-
}
179-
180-
None
181-
}
182-
183134
fn check_or_filter<'hir>(ctx: &LateContext<'hir>, path: &Path) -> Vec<(DefId, Span)> {
184135
let mut local_required_types = Vec::new();
185136
let mut local_with_types = Vec::new();
@@ -190,15 +141,23 @@ fn check_or_filter<'hir>(ctx: &LateContext<'hir>, path: &Path) -> Vec<(DefId, Sp
190141
if let TyKind::Tup(types) = tuple.kind {
191142
for typ in types {
192143
if let TyKind::Path(QPath::Resolved(_, path)) = typ.kind {
193-
if path_matches_symbol_path(ctx, path, bevy_paths::ADDED)
194-
|| path_matches_symbol_path(ctx, path, bevy_paths::CHANGED)
144+
if bevy_helpers::path_matches_symbol_path(ctx, path, bevy_paths::ADDED)
145+
|| bevy_helpers::path_matches_symbol_path(
146+
ctx,
147+
path,
148+
bevy_paths::CHANGED,
149+
)
195150
{
196-
if let Some(def_id) = get_def_id_of_first_generic_arg(path) {
151+
if let Some(def_id) =
152+
bevy_helpers::get_def_id_of_first_generic_arg(path)
153+
{
197154
local_required_types.push(def_id);
198155
}
199156
}
200-
if path_matches_symbol_path(ctx, path, bevy_paths::WITH) {
201-
if let Some(def_id) = get_def_id_of_first_generic_arg(path) {
157+
if bevy_helpers::path_matches_symbol_path(ctx, path, bevy_paths::WITH) {
158+
if let Some(def_id) =
159+
bevy_helpers::get_def_id_of_first_generic_arg(path)
160+
{
202161
local_with_types.push((def_id, typ.span));
203162
}
204163
}

0 commit comments

Comments
 (0)