aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/diagnostics/incorrect_case.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/diagnostics/incorrect_case.rs')
-rw-r--r--crates/ide/src/diagnostics/incorrect_case.rs488
1 files changed, 0 insertions, 488 deletions
diff --git a/crates/ide/src/diagnostics/incorrect_case.rs b/crates/ide/src/diagnostics/incorrect_case.rs
deleted file mode 100644
index 832394400..000000000
--- a/crates/ide/src/diagnostics/incorrect_case.rs
+++ /dev/null
@@ -1,488 +0,0 @@
1use hir::{db::AstDatabase, InFile};
2use ide_assists::Assist;
3use ide_db::base_db::FilePosition;
4use syntax::AstNode;
5
6use crate::{
7 diagnostics::{unresolved_fix, Diagnostic, DiagnosticsContext},
8 references::rename::rename_with_semantics,
9 Severity,
10};
11
12// Diagnostic: incorrect-ident-case
13//
14// This diagnostic is triggered if an item name doesn't follow https://doc.rust-lang.org/1.0.0/style/style/naming/README.html[Rust naming convention].
15pub(super) fn incorrect_case(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Diagnostic {
16 Diagnostic::new(
17 "incorrect-ident-case",
18 format!(
19 "{} `{}` should have {} name, e.g. `{}`",
20 d.ident_type, d.ident_text, d.expected_case, d.suggested_text
21 ),
22 ctx.sema.diagnostics_display_range(InFile::new(d.file, d.ident.clone().into())).range,
23 )
24 .severity(Severity::WeakWarning)
25 .with_fixes(fixes(ctx, d))
26}
27
28fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Option<Vec<Assist>> {
29 let root = ctx.sema.db.parse_or_expand(d.file)?;
30 let name_node = d.ident.to_node(&root);
31
32 let name_node = InFile::new(d.file, name_node.syntax());
33 let frange = name_node.original_file_range(ctx.sema.db);
34 let file_position = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
35
36 let label = format!("Rename to {}", d.suggested_text);
37 let mut res = unresolved_fix("change_case", &label, frange.range);
38 if ctx.resolve.should_resolve(&res.id) {
39 let source_change = rename_with_semantics(&ctx.sema, file_position, &d.suggested_text);
40 res.source_change = Some(source_change.ok().unwrap_or_default());
41 }
42
43 Some(vec![res])
44}
45
46#[cfg(test)]
47mod change_case {
48 use crate::{
49 diagnostics::tests::{check_diagnostics, check_fix},
50 fixture, AssistResolveStrategy, DiagnosticsConfig,
51 };
52
53 #[test]
54 fn test_rename_incorrect_case() {
55 check_fix(
56 r#"
57pub struct test_struct$0 { one: i32 }
58
59pub fn some_fn(val: test_struct) -> test_struct {
60 test_struct { one: val.one + 1 }
61}
62"#,
63 r#"
64pub struct TestStruct { one: i32 }
65
66pub fn some_fn(val: TestStruct) -> TestStruct {
67 TestStruct { one: val.one + 1 }
68}
69"#,
70 );
71
72 check_fix(
73 r#"
74pub fn some_fn(NonSnakeCase$0: u8) -> u8 {
75 NonSnakeCase
76}
77"#,
78 r#"
79pub fn some_fn(non_snake_case: u8) -> u8 {
80 non_snake_case
81}
82"#,
83 );
84
85 check_fix(
86 r#"
87pub fn SomeFn$0(val: u8) -> u8 {
88 if val != 0 { SomeFn(val - 1) } else { val }
89}
90"#,
91 r#"
92pub fn some_fn(val: u8) -> u8 {
93 if val != 0 { some_fn(val - 1) } else { val }
94}
95"#,
96 );
97
98 check_fix(
99 r#"
100fn some_fn() {
101 let whatAWeird_Formatting$0 = 10;
102 another_func(whatAWeird_Formatting);
103}
104"#,
105 r#"
106fn some_fn() {
107 let what_a_weird_formatting = 10;
108 another_func(what_a_weird_formatting);
109}
110"#,
111 );
112 }
113
114 #[test]
115 fn test_uppercase_const_no_diagnostics() {
116 check_diagnostics(
117 r#"
118fn foo() {
119 const ANOTHER_ITEM$0: &str = "some_item";
120}
121"#,
122 );
123 }
124
125 #[test]
126 fn test_rename_incorrect_case_struct_method() {
127 check_fix(
128 r#"
129pub struct TestStruct;
130
131impl TestStruct {
132 pub fn SomeFn$0() -> TestStruct {
133 TestStruct
134 }
135}
136"#,
137 r#"
138pub struct TestStruct;
139
140impl TestStruct {
141 pub fn some_fn() -> TestStruct {
142 TestStruct
143 }
144}
145"#,
146 );
147 }
148
149 #[test]
150 fn test_single_incorrect_case_diagnostic_in_function_name_issue_6970() {
151 let input = r#"fn FOO$0() {}"#;
152 let expected = r#"fn foo() {}"#;
153
154 let (analysis, file_position) = fixture::position(input);
155 let diagnostics = analysis
156 .diagnostics(
157 &DiagnosticsConfig::default(),
158 AssistResolveStrategy::All,
159 file_position.file_id,
160 )
161 .unwrap();
162 assert_eq!(diagnostics.len(), 1);
163
164 check_fix(input, expected);
165 }
166
167 #[test]
168 fn incorrect_function_name() {
169 check_diagnostics(
170 r#"
171fn NonSnakeCaseName() {}
172// ^^^^^^^^^^^^^^^^ Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
173"#,
174 );
175 }
176
177 #[test]
178 fn incorrect_function_params() {
179 check_diagnostics(
180 r#"
181fn foo(SomeParam: u8) {}
182 // ^^^^^^^^^ Parameter `SomeParam` should have snake_case name, e.g. `some_param`
183
184fn foo2(ok_param: &str, CAPS_PARAM: u8) {}
185 // ^^^^^^^^^^ Parameter `CAPS_PARAM` should have snake_case name, e.g. `caps_param`
186"#,
187 );
188 }
189
190 #[test]
191 fn incorrect_variable_names() {
192 check_diagnostics(
193 r#"
194fn foo() {
195 let SOME_VALUE = 10;
196 // ^^^^^^^^^^ Variable `SOME_VALUE` should have snake_case name, e.g. `some_value`
197 let AnotherValue = 20;
198 // ^^^^^^^^^^^^ Variable `AnotherValue` should have snake_case name, e.g. `another_value`
199}
200"#,
201 );
202 }
203
204 #[test]
205 fn incorrect_struct_names() {
206 check_diagnostics(
207 r#"
208struct non_camel_case_name {}
209 // ^^^^^^^^^^^^^^^^^^^ Structure `non_camel_case_name` should have CamelCase name, e.g. `NonCamelCaseName`
210
211struct SCREAMING_CASE {}
212 // ^^^^^^^^^^^^^^ Structure `SCREAMING_CASE` should have CamelCase name, e.g. `ScreamingCase`
213"#,
214 );
215 }
216
217 #[test]
218 fn no_diagnostic_for_camel_cased_acronyms_in_struct_name() {
219 check_diagnostics(
220 r#"
221struct AABB {}
222"#,
223 );
224 }
225
226 #[test]
227 fn incorrect_struct_field() {
228 check_diagnostics(
229 r#"
230struct SomeStruct { SomeField: u8 }
231 // ^^^^^^^^^ Field `SomeField` should have snake_case name, e.g. `some_field`
232"#,
233 );
234 }
235
236 #[test]
237 fn incorrect_enum_names() {
238 check_diagnostics(
239 r#"
240enum some_enum { Val(u8) }
241 // ^^^^^^^^^ Enum `some_enum` should have CamelCase name, e.g. `SomeEnum`
242
243enum SOME_ENUM {}
244 // ^^^^^^^^^ Enum `SOME_ENUM` should have CamelCase name, e.g. `SomeEnum`
245"#,
246 );
247 }
248
249 #[test]
250 fn no_diagnostic_for_camel_cased_acronyms_in_enum_name() {
251 check_diagnostics(
252 r#"
253enum AABB {}
254"#,
255 );
256 }
257
258 #[test]
259 fn incorrect_enum_variant_name() {
260 check_diagnostics(
261 r#"
262enum SomeEnum { SOME_VARIANT(u8) }
263 // ^^^^^^^^^^^^ Variant `SOME_VARIANT` should have CamelCase name, e.g. `SomeVariant`
264"#,
265 );
266 }
267
268 #[test]
269 fn incorrect_const_name() {
270 check_diagnostics(
271 r#"
272const some_weird_const: u8 = 10;
273 // ^^^^^^^^^^^^^^^^ Constant `some_weird_const` should have UPPER_SNAKE_CASE name, e.g. `SOME_WEIRD_CONST`
274"#,
275 );
276 }
277
278 #[test]
279 fn incorrect_static_name() {
280 check_diagnostics(
281 r#"
282static some_weird_const: u8 = 10;
283 // ^^^^^^^^^^^^^^^^ Static variable `some_weird_const` should have UPPER_SNAKE_CASE name, e.g. `SOME_WEIRD_CONST`
284"#,
285 );
286 }
287
288 #[test]
289 fn fn_inside_impl_struct() {
290 check_diagnostics(
291 r#"
292struct someStruct;
293 // ^^^^^^^^^^ Structure `someStruct` should have CamelCase name, e.g. `SomeStruct`
294
295impl someStruct {
296 fn SomeFunc(&self) {
297 // ^^^^^^^^ Function `SomeFunc` should have snake_case name, e.g. `some_func`
298 let WHY_VAR_IS_CAPS = 10;
299 // ^^^^^^^^^^^^^^^ Variable `WHY_VAR_IS_CAPS` should have snake_case name, e.g. `why_var_is_caps`
300 }
301}
302"#,
303 );
304 }
305
306 #[test]
307 fn no_diagnostic_for_enum_varinats() {
308 check_diagnostics(
309 r#"
310enum Option { Some, None }
311
312fn main() {
313 match Option::None {
314 None => (),
315 Some => (),
316 }
317}
318"#,
319 );
320 }
321
322 #[test]
323 fn non_let_bind() {
324 check_diagnostics(
325 r#"
326enum Option { Some, None }
327
328fn main() {
329 match Option::None {
330 SOME_VAR @ None => (),
331 // ^^^^^^^^ Variable `SOME_VAR` should have snake_case name, e.g. `some_var`
332 Some => (),
333 }
334}
335"#,
336 );
337 }
338
339 #[test]
340 fn allow_attributes_crate_attr() {
341 check_diagnostics(
342 r#"
343#![allow(non_snake_case)]
344
345mod F {
346 fn CheckItWorksWithCrateAttr(BAD_NAME_HI: u8) {}
347}
348 "#,
349 );
350 }
351
352 #[test]
353 #[ignore]
354 fn bug_trait_inside_fn() {
355 // FIXME:
356 // This is broken, and in fact, should not even be looked at by this
357 // lint in the first place. There's weird stuff going on in the
358 // collection phase.
359 // It's currently being brought in by:
360 // * validate_func on `a` recursing into modules
361 // * then it finds the trait and then the function while iterating
362 // through modules
363 // * then validate_func is called on Dirty
364 // * ... which then proceeds to look at some unknown module taking no
365 // attrs from either the impl or the fn a, and then finally to the root
366 // module
367 //
368 // It should find the attribute on the trait, but it *doesn't even see
369 // the trait* as far as I can tell.
370
371 check_diagnostics(
372 r#"
373trait T { fn a(); }
374struct U {}
375impl T for U {
376 fn a() {
377 // this comes out of bitflags, mostly
378 #[allow(non_snake_case)]
379 trait __BitFlags {
380 const HiImAlsoBad: u8 = 2;
381 #[inline]
382 fn Dirty(&self) -> bool {
383 false
384 }
385 }
386
387 }
388}
389 "#,
390 );
391 }
392
393 #[test]
394 fn infinite_loop_inner_items() {
395 check_diagnostics(
396 r#"
397fn qualify() {
398 mod foo {
399 use super::*;
400 }
401}
402 "#,
403 )
404 }
405
406 #[test] // Issue #8809.
407 fn parenthesized_parameter() {
408 check_diagnostics(r#"fn f((O): _) {}"#)
409 }
410
411 #[test]
412 fn ignores_extern_items() {
413 cov_mark::check!(extern_func_incorrect_case_ignored);
414 cov_mark::check!(extern_static_incorrect_case_ignored);
415 check_diagnostics(
416 r#"
417extern {
418 fn NonSnakeCaseName(SOME_VAR: u8) -> u8;
419 pub static SomeStatic: u8 = 10;
420}
421 "#,
422 );
423 }
424
425 #[test]
426 #[ignore]
427 fn bug_traits_arent_checked() {
428 // FIXME: Traits and functions in traits aren't currently checked by
429 // r-a, even though rustc will complain about them.
430 check_diagnostics(
431 r#"
432trait BAD_TRAIT {
433 // ^^^^^^^^^ Trait `BAD_TRAIT` should have CamelCase name, e.g. `BadTrait`
434 fn BAD_FUNCTION();
435 // ^^^^^^^^^^^^ Function `BAD_FUNCTION` should have snake_case name, e.g. `bad_function`
436 fn BadFunction();
437 // ^^^^^^^^^^^^ Function `BadFunction` should have snake_case name, e.g. `bad_function`
438}
439 "#,
440 );
441 }
442
443 #[test]
444 fn allow_attributes() {
445 check_diagnostics(
446 r#"
447#[allow(non_snake_case)]
448fn NonSnakeCaseName(SOME_VAR: u8) -> u8{
449 // cov_flags generated output from elsewhere in this file
450 extern "C" {
451 #[no_mangle]
452 static lower_case: u8;
453 }
454
455 let OtherVar = SOME_VAR + 1;
456 OtherVar
457}
458
459#[allow(nonstandard_style)]
460mod CheckNonstandardStyle {
461 fn HiImABadFnName() {}
462}
463
464#[allow(bad_style)]
465mod CheckBadStyle {
466 fn HiImABadFnName() {}
467}
468
469mod F {
470 #![allow(non_snake_case)]
471 fn CheckItWorksWithModAttr(BAD_NAME_HI: u8) {}
472}
473
474#[allow(non_snake_case, non_camel_case_types)]
475pub struct some_type {
476 SOME_FIELD: u8,
477 SomeField: u16,
478}
479
480#[allow(non_upper_case_globals)]
481pub const some_const: u8 = 10;
482
483#[allow(non_upper_case_globals)]
484pub static SomeStatic: u8 = 10;
485 "#,
486 );
487 }
488}