aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/hover.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-06-04 17:35:19 +0100
committerLukas Wirth <[email protected]>2021-06-04 17:35:19 +0100
commit343df88ac7579316a5500fa7f4a07602809af669 (patch)
tree09db0d170e3fa31c118e6d0dce62af98f51ac5e0 /crates/ide/src/hover.rs
parent5d17b6a6873d530eda89d271807dcb70a811a200 (diff)
Generate default lint completions
Diffstat (limited to 'crates/ide/src/hover.rs')
-rw-r--r--crates/ide/src/hover.rs75
1 files changed, 60 insertions, 15 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 4d91c5c4f..f3f6f749c 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -3,11 +3,13 @@ use hir::{
3 AsAssocItem, AssocItemContainer, GenericParam, HasAttrs, HasSource, HirDisplay, InFile, Module, 3 AsAssocItem, AssocItemContainer, GenericParam, HasAttrs, HasSource, HirDisplay, InFile, Module,
4 ModuleDef, Semantics, 4 ModuleDef, Semantics,
5}; 5};
6use ide_completion::generated_lint_completions::{CLIPPY_LINTS, FEATURES};
7use ide_db::{ 6use ide_db::{
8 base_db::SourceDatabase, 7 base_db::SourceDatabase,
9 defs::{Definition, NameClass, NameRefClass}, 8 defs::{Definition, NameClass, NameRefClass},
10 helpers::FamousDefs, 9 helpers::{
10 generated_lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
11 FamousDefs,
12 },
11 RootDatabase, 13 RootDatabase,
12}; 14};
13use itertools::Itertools; 15use itertools::Itertools;
@@ -206,25 +208,36 @@ fn try_hover_for_attribute(token: &SyntaxToken) -> Option<RangeInfo<HoverResult>
206 if !tt.syntax().text_range().contains(token.text_range().start()) { 208 if !tt.syntax().text_range().contains(token.text_range().start()) {
207 return None; 209 return None;
208 } 210 }
209 let lints = match &*path { 211 let (is_clippy, lints) = match &*path {
210 "feature" => FEATURES, 212 "feature" => (false, FEATURES),
211 "allow" | "warn" | "forbid" | "error" => { 213 "allow" | "deny" | "forbid" | "warn" => {
212 let is_clippy = algo::skip_trivia_token(token.clone(), Direction::Prev) 214 let is_clippy = algo::non_trivia_sibling(token.clone().into(), Direction::Prev)
213 .filter(|t| t.kind() == T![::]) 215 .filter(|t| t.kind() == T![:])
214 .and_then(|t| algo::skip_trivia_token(t, Direction::Prev)) 216 .and_then(|t| algo::non_trivia_sibling(t, Direction::Prev))
215 .map_or(false, |t| t.kind() == T![ident] && t.text() == "clippy"); 217 .filter(|t| t.kind() == T![:])
218 .and_then(|t| algo::non_trivia_sibling(t, Direction::Prev))
219 .map_or(false, |t| {
220 t.kind() == T![ident] && t.into_token().map_or(false, |t| t.text() == "clippy")
221 });
216 if is_clippy { 222 if is_clippy {
217 CLIPPY_LINTS 223 (true, CLIPPY_LINTS)
218 } else { 224 } else {
219 &[] 225 (false, DEFAULT_LINTS)
220 } 226 }
221 } 227 }
222 _ => return None, 228 _ => return None,
223 }; 229 };
224 let lint = lints 230
225 .binary_search_by_key(&token.text(), |lint| lint.label) 231 let tmp;
226 .ok() 232 let needle = if is_clippy {
227 .map(|idx| &FEATURES[idx])?; 233 tmp = format!("clippy::{}", token.text());
234 &tmp
235 } else {
236 &*token.text()
237 };
238
239 let lint =
240 lints.binary_search_by_key(&needle, |lint| lint.label).ok().map(|idx| &lints[idx])?;
228 Some(RangeInfo::new( 241 Some(RangeInfo::new(
229 token.text_range(), 242 token.text_range(),
230 HoverResult { 243 HoverResult {
@@ -4055,4 +4068,36 @@ pub fn foo() {}
4055 "##]], 4068 "##]],
4056 ) 4069 )
4057 } 4070 }
4071
4072 #[test]
4073 fn hover_lint() {
4074 check(
4075 r#"#![allow(arithmetic_overflow$0)]"#,
4076 expect![[r#"
4077 *arithmetic_overflow*
4078 ```
4079 arithmetic_overflow
4080 ```
4081 ___
4082
4083 arithmetic operation overflows
4084 "#]],
4085 )
4086 }
4087
4088 #[test]
4089 fn hover_clippy_lint() {
4090 check(
4091 r#"#![allow(clippy::almost_swapped$0)]"#,
4092 expect![[r#"
4093 *almost_swapped*
4094 ```
4095 clippy::almost_swapped
4096 ```
4097 ___
4098
4099 Checks for `foo = bar; bar = foo` sequences.
4100 "#]],
4101 )
4102 }
4058} 4103}