aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/diagnostics.rs87
1 files changed, 50 insertions, 37 deletions
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index 55593a8cb..043ce357b 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -62,12 +62,18 @@ pub(crate) fn diagnostics(
62 } 62 }
63 .into(), 63 .into(),
64 ); 64 );
65 let fix = sema
66 .diagnostic_fix_source(d)
67 .map(|unresolved_module| unresolved_module.syntax().text_range())
68 .map(|fix_range| (fix, fix_range));
69
65 res.borrow_mut().push(Diagnostic { 70 res.borrow_mut().push(Diagnostic {
66 range: sema.diagnostics_presentation_range(d).range, 71 range: sema.diagnostics_presentation_range(d).range,
67 message: d.message(), 72 message: d.message(),
68 severity: Severity::Error, 73 severity: Severity::Error,
69 fix: Some((fix, sema.diagnostic_fix_source(d).syntax().text_range())), 74 fix,
70 }) 75 });
76 Some(())
71 }) 77 })
72 .on::<hir::diagnostics::MissingFields, _>(|d| { 78 .on::<hir::diagnostics::MissingFields, _>(|d| {
73 // Note that although we could add a diagnostics to 79 // Note that although we could add a diagnostics to
@@ -78,30 +84,29 @@ pub(crate) fn diagnostics(
78 let fix = if d.missed_fields.iter().any(|it| it.as_tuple_index().is_some()) { 84 let fix = if d.missed_fields.iter().any(|it| it.as_tuple_index().is_some()) {
79 None 85 None
80 } else { 86 } else {
81 let record_expr = sema.diagnostic_fix_source(d); 87 sema.diagnostic_fix_source(d)
82 if let Some(old_field_list) = record_expr.record_expr_field_list() { 88 .and_then(|record_expr| record_expr.record_expr_field_list())
83 let mut new_field_list = old_field_list.clone(); 89 .map(|old_field_list| {
84 for f in d.missed_fields.iter() { 90 let mut new_field_list = old_field_list.clone();
85 let field = make::record_expr_field( 91 for f in d.missed_fields.iter() {
86 make::name_ref(&f.to_string()), 92 let field = make::record_expr_field(
87 Some(make::expr_unit()), 93 make::name_ref(&f.to_string()),
88 ); 94 Some(make::expr_unit()),
89 new_field_list = new_field_list.append_field(&field); 95 );
90 } 96 new_field_list = new_field_list.append_field(&field);
91 97 }
92 let edit = { 98
93 let mut builder = TextEditBuilder::default(); 99 let edit = {
94 algo::diff(&old_field_list.syntax(), &new_field_list.syntax()) 100 let mut builder = TextEditBuilder::default();
95 .into_text_edit(&mut builder); 101 algo::diff(&old_field_list.syntax(), &new_field_list.syntax())
96 builder.finish() 102 .into_text_edit(&mut builder);
97 }; 103 builder.finish()
98 Some(( 104 };
99 Fix::new("Fill struct fields", SourceFileEdit { file_id, edit }.into()), 105 (
100 sema.original_range(&old_field_list.syntax()).range, 106 Fix::new("Fill struct fields", SourceFileEdit { file_id, edit }.into()),
101 )) 107 sema.original_range(&old_field_list.syntax()).range,
102 } else { 108 )
103 None 109 })
104 }
105 }; 110 };
106 111
107 res.borrow_mut().push(Diagnostic { 112 res.borrow_mut().push(Diagnostic {
@@ -109,28 +114,36 @@ pub(crate) fn diagnostics(
109 message: d.message(), 114 message: d.message(),
110 severity: Severity::Error, 115 severity: Severity::Error,
111 fix, 116 fix,
112 }) 117 });
118 Some(())
113 }) 119 })
114 .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| { 120 .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| {
115 let tail_expr = sema.diagnostic_fix_source(d); 121 let fix = sema.diagnostic_fix_source(d).map(|tail_expr| {
116 let tail_expr_range = tail_expr.syntax().text_range(); 122 let tail_expr_range = tail_expr.syntax().text_range();
117 let edit = TextEdit::replace(tail_expr_range, format!("Ok({})", tail_expr.syntax())); 123 let edit =
118 let source_change = SourceFileEdit { file_id, edit }.into(); 124 TextEdit::replace(tail_expr_range, format!("Ok({})", tail_expr.syntax()));
125 let source_change = SourceFileEdit { file_id, edit }.into();
126 (Fix::new("Wrap with ok", source_change), tail_expr_range)
127 });
128
119 res.borrow_mut().push(Diagnostic { 129 res.borrow_mut().push(Diagnostic {
120 range: sema.diagnostics_presentation_range(d).range, 130 range: sema.diagnostics_presentation_range(d).range,
121 message: d.message(), 131 message: d.message(),
122 severity: Severity::Error, 132 severity: Severity::Error,
123 fix: Some((Fix::new("Wrap with ok", source_change), tail_expr_range)), 133 fix,
124 }) 134 });
135 Some(())
125 }) 136 })
126 .on::<hir::diagnostics::NoSuchField, _>(|d| { 137 .on::<hir::diagnostics::NoSuchField, _>(|d| {
127 res.borrow_mut().push(Diagnostic { 138 res.borrow_mut().push(Diagnostic {
128 range: sema.diagnostics_presentation_range(d).range, 139 range: sema.diagnostics_presentation_range(d).range,
129 message: d.message(), 140 message: d.message(),
130 severity: Severity::Error, 141 severity: Severity::Error,
131 fix: missing_struct_field_fix(&sema, file_id, d) 142 fix: missing_struct_field_fix(&sema, file_id, d).and_then(|fix| {
132 .map(|fix| (fix, sema.diagnostic_fix_source(d).syntax().text_range())), 143 Some((fix, sema.diagnostic_fix_source(d)?.syntax().text_range()))
133 }) 144 }),
145 });
146 Some(())
134 }) 147 })
135 // Only collect experimental diagnostics when they're enabled. 148 // Only collect experimental diagnostics when they're enabled.
136 .filter(|diag| !diag.is_experimental() || enable_experimental) 149 .filter(|diag| !diag.is_experimental() || enable_experimental)
@@ -156,7 +169,7 @@ fn missing_struct_field_fix(
156 usage_file_id: FileId, 169 usage_file_id: FileId,
157 d: &hir::diagnostics::NoSuchField, 170 d: &hir::diagnostics::NoSuchField,
158) -> Option<Fix> { 171) -> Option<Fix> {
159 let record_expr_field = sema.diagnostic_fix_source(d); 172 let record_expr_field = sema.diagnostic_fix_source(d)?;
160 173
161 let record_lit = ast::RecordExpr::cast(record_expr_field.syntax().parent()?.parent()?)?; 174 let record_lit = ast::RecordExpr::cast(record_expr_field.syntax().parent()?.parent()?)?;
162 let def_id = sema.resolve_variant(record_lit)?; 175 let def_id = sema.resolve_variant(record_lit)?;