aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs80
-rw-r--r--crates/ra_hir/src/db.rs3
-rw-r--r--crates/ra_hir/src/docs.rs81
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/nameres.rs2
-rw-r--r--crates/ra_hir/src/resolve.rs4
-rw-r--r--crates/ra_hir/src/source_binder.rs30
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs5
-rw-r--r--crates/ra_ide_api/src/name_ref_kind.rs5
-rw-r--r--crates/ra_lsp_server/src/conv.rs2
-rw-r--r--crates/ra_lsp_server/src/markdown.rs23
11 files changed, 109 insertions, 128 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 6ee6bd627..27850028b 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -12,7 +12,6 @@ use crate::{
12 ty::{TraitRef, InferenceResult, primitive::{IntTy, FloatTy, Signedness, IntBitness, FloatBitness}}, 12 ty::{TraitRef, InferenceResult, primitive::{IntTy, FloatTy, Signedness, IntBitness, FloatBitness}},
13 adt::{EnumVariantId, StructFieldId, VariantDef}, 13 adt::{EnumVariantId, StructFieldId, VariantDef},
14 generics::HasGenericParams, 14 generics::HasGenericParams,
15 docs::{Documentation, Docs, docs_from_ast},
16 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeAliasId, MacroDefId}, 15 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeAliasId, MacroDefId},
17 impl_block::ImplBlock, 16 impl_block::ImplBlock,
18 resolve::Resolver, 17 resolve::Resolver,
@@ -197,7 +196,7 @@ impl Module {
197 /// `None` for the crate root. 196 /// `None` for the crate root.
198 pub fn declaration_source( 197 pub fn declaration_source(
199 self, 198 self,
200 db: &impl HirDatabase, 199 db: &(impl DefDatabase + AstDatabase),
201 ) -> Option<(HirFileId, TreeArc<ast::Module>)> { 200 ) -> Option<(HirFileId, TreeArc<ast::Module>)> {
202 let def_map = db.crate_def_map(self.krate); 201 let def_map = db.crate_def_map(self.krate);
203 let decl = def_map[self.module_id].declaration?; 202 let decl = def_map[self.module_id].declaration?;
@@ -319,12 +318,6 @@ impl Module {
319 } 318 }
320} 319}
321 320
322impl Docs for Module {
323 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
324 self.declaration_source(db).and_then(|it| docs_from_ast(&*it.1))
325 }
326}
327
328#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 321#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
329pub struct StructField { 322pub struct StructField {
330 pub(crate) parent: VariantDef, 323 pub(crate) parent: VariantDef,
@@ -355,15 +348,6 @@ impl StructField {
355 } 348 }
356} 349}
357 350
358impl Docs for StructField {
359 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
360 match self.source(db).1 {
361 FieldSource::Named(named) => docs_from_ast(&*named),
362 FieldSource::Pos(..) => return None,
363 }
364 }
365}
366
367#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 351#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
368pub struct Struct { 352pub struct Struct {
369 pub(crate) id: StructId, 353 pub(crate) id: StructId,
@@ -425,12 +409,6 @@ impl Struct {
425 } 409 }
426} 410}
427 411
428impl Docs for Struct {
429 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
430 docs_from_ast(&*self.source(db).1)
431 }
432}
433
434#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 412#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
435pub struct Union { 413pub struct Union {
436 pub(crate) id: StructId, 414 pub(crate) id: StructId,
@@ -464,12 +442,6 @@ impl Union {
464 } 442 }
465} 443}
466 444
467impl Docs for Union {
468 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
469 docs_from_ast(&*self.source(db).1)
470 }
471}
472
473#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 445#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
474pub struct Enum { 446pub struct Enum {
475 pub(crate) id: EnumId, 447 pub(crate) id: EnumId,
@@ -519,12 +491,6 @@ impl Enum {
519 } 491 }
520} 492}
521 493
522impl Docs for Enum {
523 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
524 docs_from_ast(&*self.source(db).1)
525 }
526}
527
528#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 494#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
529pub struct EnumVariant { 495pub struct EnumVariant {
530 pub(crate) parent: Enum, 496 pub(crate) parent: Enum,
@@ -568,12 +534,6 @@ impl EnumVariant {
568 } 534 }
569} 535}
570 536
571impl Docs for EnumVariant {
572 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
573 docs_from_ast(&*self.source(db).1)
574 }
575}
576
577/// The defs which have a body. 537/// The defs which have a body.
578#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 538#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
579pub enum DefWithBody { 539pub enum DefWithBody {
@@ -757,12 +717,6 @@ impl Function {
757 } 717 }
758} 718}
759 719
760impl Docs for Function {
761 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
762 docs_from_ast(&*self.source(db).1)
763 }
764}
765
766#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 720#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
767pub struct Const { 721pub struct Const {
768 pub(crate) id: ConstId, 722 pub(crate) id: ConstId,
@@ -806,12 +760,6 @@ impl Const {
806 } 760 }
807} 761}
808 762
809impl Docs for Const {
810 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
811 docs_from_ast(&*self.source(db).1)
812 }
813}
814
815/// The declared signature of a const. 763/// The declared signature of a const.
816#[derive(Debug, Clone, PartialEq, Eq)] 764#[derive(Debug, Clone, PartialEq, Eq)]
817pub struct ConstSignature { 765pub struct ConstSignature {
@@ -884,12 +832,6 @@ impl Static {
884 } 832 }
885} 833}
886 834
887impl Docs for Static {
888 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
889 docs_from_ast(&*self.source(db).1)
890 }
891}
892
893#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 835#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
894pub struct Trait { 836pub struct Trait {
895 pub(crate) id: TraitId, 837 pub(crate) id: TraitId,
@@ -936,12 +878,6 @@ impl Trait {
936 } 878 }
937} 879}
938 880
939impl Docs for Trait {
940 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
941 docs_from_ast(&*self.source(db).1)
942 }
943}
944
945#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 881#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
946pub struct TypeAlias { 882pub struct TypeAlias {
947 pub(crate) id: TypeAliasId, 883 pub(crate) id: TypeAliasId,
@@ -998,16 +934,20 @@ impl TypeAlias {
998 } 934 }
999} 935}
1000 936
1001impl Docs for TypeAlias {
1002 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
1003 docs_from_ast(&*self.source(db).1)
1004 }
1005}
1006#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 937#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1007pub struct MacroDef { 938pub struct MacroDef {
1008 pub(crate) id: MacroDefId, 939 pub(crate) id: MacroDefId,
1009} 940}
1010 941
942impl MacroDef {
943 pub fn source(
944 &self,
945 db: &(impl DefDatabase + AstDatabase),
946 ) -> (HirFileId, TreeArc<ast::MacroCall>) {
947 (self.id.0.file_id(), self.id.0.to_node(db))
948 }
949}
950
1011pub enum Container { 951pub enum Container {
1012 Trait(Trait), 952 Trait(Trait),
1013 ImplBlock(ImplBlock), 953 ImplBlock(ImplBlock),
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 3afd0994c..d2a372f3b 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -127,6 +127,9 @@ pub trait DefDatabase: SourceDatabase {
127 127
128 #[salsa::invoke(crate::lang_item::LangItems::lang_item_query)] 128 #[salsa::invoke(crate::lang_item::LangItems::lang_item_query)]
129 fn lang_item(&self, start_crate: Crate, item: SmolStr) -> Option<LangItemTarget>; 129 fn lang_item(&self, start_crate: Crate, item: SmolStr) -> Option<LangItemTarget>;
130
131 #[salsa::invoke(crate::docs::documentation_query)]
132 fn documentation(&self, def: crate::docs::DocDef) -> Option<crate::docs::Documentation>;
130} 133}
131 134
132#[salsa::query_group(HirDatabaseStorage)] 135#[salsa::query_group(HirDatabaseStorage)]
diff --git a/crates/ra_hir/src/docs.rs b/crates/ra_hir/src/docs.rs
index 5db72c08a..1b0f84de5 100644
--- a/crates/ra_hir/src/docs.rs
+++ b/crates/ra_hir/src/docs.rs
@@ -1,24 +1,60 @@
1use std::sync::Arc;
2
1use ra_syntax::ast; 3use ra_syntax::ast;
2 4
3use crate::HirDatabase; 5use crate::{
6 HirDatabase, DefDatabase, AstDatabase,
7 Module, StructField, Struct, Enum, EnumVariant, Static, Const, Function, Union, Trait, TypeAlias, FieldSource, MacroDef,
8};
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
11pub enum DocDef {
12 Module(Module),
13 StructField(StructField),
14 Struct(Struct),
15 Enum(Enum),
16 EnumVariant(EnumVariant),
17 Static(Static),
18 Const(Const),
19 Function(Function),
20 Union(Union),
21 Trait(Trait),
22 TypeAlias(TypeAlias),
23 MacroDef(MacroDef),
24}
25
26impl_froms!(
27 DocDef: Module,
28 StructField,
29 Struct,
30 Enum,
31 EnumVariant,
32 Static,
33 Const,
34 Function,
35 Union,
36 Trait,
37 TypeAlias,
38 MacroDef
39);
4 40
5/// Holds documentation 41/// Holds documentation
6#[derive(Debug, Clone)] 42#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct Documentation(String); 43pub struct Documentation(Arc<str>);
8 44
9impl Documentation { 45impl Documentation {
10 pub fn new(s: &str) -> Self { 46 fn new(s: &str) -> Documentation {
11 Self(s.into()) 47 Documentation(s.into())
12 } 48 }
13 49
14 pub fn contents(&self) -> &str { 50 pub fn as_str(&self) -> &str {
15 &self.0 51 &*self.0
16 } 52 }
17} 53}
18 54
19impl Into<String> for Documentation { 55impl Into<String> for Documentation {
20 fn into(self) -> String { 56 fn into(self) -> String {
21 self.contents().into() 57 self.as_str().to_owned()
22 } 58 }
23} 59}
24 60
@@ -29,3 +65,32 @@ pub trait Docs {
29pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> { 65pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> {
30 node.doc_comment_text().map(|it| Documentation::new(&it)) 66 node.doc_comment_text().map(|it| Documentation::new(&it))
31} 67}
68
69pub(crate) fn documentation_query(
70 db: &(impl DefDatabase + AstDatabase),
71 def: DocDef,
72) -> Option<Documentation> {
73 match def {
74 DocDef::Module(it) => docs_from_ast(&*it.declaration_source(db)?.1),
75 DocDef::StructField(it) => match it.source(db).1 {
76 FieldSource::Named(named) => docs_from_ast(&*named),
77 FieldSource::Pos(..) => return None,
78 },
79 DocDef::Struct(it) => docs_from_ast(&*it.source(db).1),
80 DocDef::Enum(it) => docs_from_ast(&*it.source(db).1),
81 DocDef::EnumVariant(it) => docs_from_ast(&*it.source(db).1),
82 DocDef::Static(it) => docs_from_ast(&*it.source(db).1),
83 DocDef::Const(it) => docs_from_ast(&*it.source(db).1),
84 DocDef::Function(it) => docs_from_ast(&*it.source(db).1),
85 DocDef::Union(it) => docs_from_ast(&*it.source(db).1),
86 DocDef::Trait(it) => docs_from_ast(&*it.source(db).1),
87 DocDef::TypeAlias(it) => docs_from_ast(&*it.source(db).1),
88 DocDef::MacroDef(it) => docs_from_ast(&*it.source(db).1),
89 }
90}
91
92impl<T: Into<DocDef> + Copy> Docs for T {
93 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
94 db.documentation((*self).into())
95 }
96}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 18dea5f17..0e4aaf678 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -69,7 +69,7 @@ pub use self::{
69 expr::ExprScopes, 69 expr::ExprScopes,
70 resolve::Resolution, 70 resolve::Resolution,
71 generics::{GenericParams, GenericParam, HasGenericParams}, 71 generics::{GenericParams, GenericParam, HasGenericParams},
72 source_binder::{SourceAnalyzer, PathResolution, ScopeEntryWithSyntax,MacroByExampleDef}, 72 source_binder::{SourceAnalyzer, PathResolution, ScopeEntryWithSyntax},
73}; 73};
74 74
75pub use self::code_model::{ 75pub use self::code_model::{
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 8b798d6c9..dc0dd23c9 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -323,6 +323,8 @@ impl CrateDefMap {
323 (res.resolved_def, res.segment_index) 323 (res.resolved_def, res.segment_index)
324 } 324 }
325 325
326 // FIXME: This seems to do the same work as `resolve_path_with_macro`, but
327 // using a completely different code path. Seems bad, huh?
326 pub(crate) fn find_macro( 328 pub(crate) fn find_macro(
327 &self, 329 &self,
328 db: &impl DefDatabase, 330 db: &impl DefDatabase,
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 0f6ee7f47..d6956f45e 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -148,8 +148,8 @@ impl Resolver {
148 PathResult::from_resolution(self.resolve_name(db, &Name::self_param())) 148 PathResult::from_resolution(self.resolve_name(db, &Name::self_param()))
149 } else { 149 } else {
150 let (item_map, module) = match self.module() { 150 let (item_map, module) = match self.module() {
151 Some(m) => m, 151 Some(it) => it,
152 _ => return PathResult::empty(), 152 None => return PathResult::empty(),
153 }; 153 };
154 let (module_res, segment_index) = item_map.resolve_path(db, module, path); 154 let (module_res, segment_index) = item_map.resolve_path(db, module, path);
155 155
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 6a5799622..410064d45 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -10,7 +10,7 @@ use std::sync::Arc;
10use rustc_hash::{FxHashSet, FxHashMap}; 10use rustc_hash::{FxHashSet, FxHashMap};
11use ra_db::{FileId, FilePosition}; 11use ra_db::{FileId, FilePosition};
12use ra_syntax::{ 12use ra_syntax::{
13 SyntaxNode, AstPtr, TextUnit, SyntaxNodePtr, TextRange,TreeArc, 13 SyntaxNode, AstPtr, TextUnit, SyntaxNodePtr, TextRange,
14 ast::{self, AstNode, NameOwner}, 14 ast::{self, AstNode, NameOwner},
15 algo::find_node_at_offset, 15 algo::find_node_at_offset,
16 SyntaxKind::*, 16 SyntaxKind::*,
@@ -18,10 +18,9 @@ use ra_syntax::{
18 18
19use crate::{ 19use crate::{
20 HirDatabase, Function, Struct, Enum, Const, Static, Either, DefWithBody, PerNs, Name, 20 HirDatabase, Function, Struct, Enum, Const, Static, Either, DefWithBody, PerNs, Name,
21 AsName, Module, HirFileId, Crate, Trait, Resolver, Ty,Path, 21 AsName, Module, HirFileId, Crate, Trait, Resolver, Ty, Path, MacroDef,
22 expr::{BodySourceMap, scope::{ScopeId, ExprScopes}}, 22 expr::{BodySourceMap, scope::{ScopeId, ExprScopes}},
23 ids::{LocationCtx, MacroDefId}, 23 ids::LocationCtx,
24 docs::{docs_from_ast,Documentation},
25 expr, AstId, 24 expr, AstId,
26}; 25};
27 26
@@ -182,27 +181,10 @@ pub enum PathResolution {
182 /// A generic parameter 181 /// A generic parameter
183 GenericParam(u32), 182 GenericParam(u32),
184 SelfType(crate::ImplBlock), 183 SelfType(crate::ImplBlock),
185 Macro(MacroByExampleDef), 184 Macro(MacroDef),
186 AssocItem(crate::ImplItem), 185 AssocItem(crate::ImplItem),
187} 186}
188 187
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
190pub struct MacroByExampleDef {
191 pub(crate) id: MacroDefId,
192}
193
194impl MacroByExampleDef {
195 pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::MacroCall>) {
196 (self.id.0.file_id(), self.id.0.to_node(db))
197 }
198}
199
200impl crate::Docs for MacroByExampleDef {
201 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
202 docs_from_ast(&*self.source(db).1)
203 }
204}
205
206#[derive(Debug, Clone, PartialEq, Eq)] 188#[derive(Debug, Clone, PartialEq, Eq)]
207pub struct ScopeEntryWithSyntax { 189pub struct ScopeEntryWithSyntax {
208 pub(crate) name: Name, 190 pub(crate) name: Name,
@@ -284,10 +266,10 @@ impl SourceAnalyzer {
284 &self, 266 &self,
285 db: &impl HirDatabase, 267 db: &impl HirDatabase,
286 macro_call: &ast::MacroCall, 268 macro_call: &ast::MacroCall,
287 ) -> Option<MacroByExampleDef> { 269 ) -> Option<MacroDef> {
288 let id = 270 let id =
289 self.resolver.resolve_macro_call(db, macro_call.path().and_then(Path::from_ast))?; 271 self.resolver.resolve_macro_call(db, macro_call.path().and_then(Path::from_ast))?;
290 Some(MacroByExampleDef { id }) 272 Some(MacroDef { id })
291 } 273 }
292 274
293 pub fn resolve_hir_path( 275 pub fn resolve_hir_path(
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index e19c071b0..45002d098 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -238,10 +238,7 @@ impl NavigationTarget {
238 } 238 }
239 } 239 }
240 240
241 pub(crate) fn from_macro_def( 241 pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget {
242 db: &RootDatabase,
243 macro_call: hir::MacroByExampleDef,
244 ) -> NavigationTarget {
245 let (file_id, node) = macro_call.source(db); 242 let (file_id, node) = macro_call.source(db);
246 log::debug!("nav target {}", node.syntax().debug_dump()); 243 log::debug!("nav target {}", node.syntax().debug_dump());
247 NavigationTarget::from_named(file_id.original_file(db), &*node) 244 NavigationTarget::from_named(file_id.original_file(db), &*node)
diff --git a/crates/ra_ide_api/src/name_ref_kind.rs b/crates/ra_ide_api/src/name_ref_kind.rs
index 90972bc58..000036db4 100644
--- a/crates/ra_ide_api/src/name_ref_kind.rs
+++ b/crates/ra_ide_api/src/name_ref_kind.rs
@@ -1,11 +1,12 @@
1use ra_syntax::{AstNode, AstPtr, ast}; 1use ra_syntax::{AstNode, AstPtr, ast};
2use hir::Either; 2use hir::Either;
3use crate::db::RootDatabase;
4use test_utils::tested_by; 3use test_utils::tested_by;
5 4
5use crate::db::RootDatabase;
6
6pub enum NameRefKind { 7pub enum NameRefKind {
7 Method(hir::Function), 8 Method(hir::Function),
8 Macro(hir::MacroByExampleDef), 9 Macro(hir::MacroDef),
9 FieldAccess(hir::StructField), 10 FieldAccess(hir::StructField),
10 AssocItem(hir::ImplItem), 11 AssocItem(hir::ImplItem),
11 Def(hir::ModuleDef), 12 Def(hir::ModuleDef),
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index 88d29b256..257492589 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -171,7 +171,7 @@ impl Conv for ra_ide_api::Documentation {
171 fn conv(self) -> Documentation { 171 fn conv(self) -> Documentation {
172 Documentation::MarkupContent(MarkupContent { 172 Documentation::MarkupContent(MarkupContent {
173 kind: MarkupKind::Markdown, 173 kind: MarkupKind::Markdown,
174 value: crate::markdown::sanitize_markdown(self).into(), 174 value: crate::markdown::mark_fenced_blocks_as_rust(self.as_str()).into(),
175 }) 175 })
176 } 176 }
177} 177}
diff --git a/crates/ra_lsp_server/src/markdown.rs b/crates/ra_lsp_server/src/markdown.rs
index f505755e8..e382eee90 100644
--- a/crates/ra_lsp_server/src/markdown.rs
+++ b/crates/ra_lsp_server/src/markdown.rs
@@ -1,26 +1,20 @@
1use ra_ide_api::Documentation; 1pub(crate) fn mark_fenced_blocks_as_rust(src: &str) -> String {
2
3pub(crate) fn sanitize_markdown(docs: Documentation) -> Documentation {
4 let docs: String = docs.into();
5
6 // Massage markdown
7 let mut processed_lines = Vec::new(); 2 let mut processed_lines = Vec::new();
8 let mut in_code_block = false; 3 let mut in_code_block = false;
9 for line in docs.lines() { 4 for line in src.lines() {
10 if line.starts_with("```") { 5 if line.starts_with("```") {
11 in_code_block = !in_code_block; 6 in_code_block ^= true
12 } 7 }
13 8
14 let line = if in_code_block && line.starts_with("```") && !line.contains("rust") { 9 let line = if in_code_block && line.starts_with("```") && !line.contains("rust") {
15 "```rust".into() 10 "```rust"
16 } else { 11 } else {
17 line.to_string() 12 line
18 }; 13 };
19 14
20 processed_lines.push(line); 15 processed_lines.push(line);
21 } 16 }
22 17 processed_lines.join("\n")
23 Documentation::new(&processed_lines.join("\n"))
24} 18}
25 19
26#[cfg(test)] 20#[cfg(test)]
@@ -30,9 +24,6 @@ mod tests {
30 #[test] 24 #[test]
31 fn test_codeblock_adds_rust() { 25 fn test_codeblock_adds_rust() {
32 let comment = "```\nfn some_rust() {}\n```"; 26 let comment = "```\nfn some_rust() {}\n```";
33 assert_eq!( 27 assert_eq!(mark_fenced_blocks_as_rust(comment), "```rust\nfn some_rust() {}\n```");
34 sanitize_markdown(Documentation::new(comment)).contents(),
35 "```rust\nfn some_rust() {}\n```"
36 );
37 } 28 }
38} 29}