diff options
Diffstat (limited to 'crates/ide/src/syntax_highlighting/inject.rs')
-rw-r--r-- | crates/ide/src/syntax_highlighting/inject.rs | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index 947cc974c..f359eacf2 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs | |||
@@ -3,8 +3,8 @@ | |||
3 | use std::{mem, ops::Range}; | 3 | use std::{mem, ops::Range}; |
4 | 4 | ||
5 | use either::Either; | 5 | use either::Either; |
6 | use hir::{HasAttrs, Semantics}; | 6 | use hir::{HasAttrs, InFile, Semantics}; |
7 | use ide_db::{call_info::ActiveParameter, defs::Definition}; | 7 | use ide_db::{call_info::ActiveParameter, defs::Definition, SymbolKind}; |
8 | use syntax::{ | 8 | use syntax::{ |
9 | ast::{self, AstNode, AttrsOwner, DocCommentsOwner}, | 9 | ast::{self, AstNode, AttrsOwner, DocCommentsOwner}, |
10 | match_ast, AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize, | 10 | match_ast, AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize, |
@@ -148,8 +148,12 @@ fn doc_attributes<'node>( | |||
148 | } | 148 | } |
149 | 149 | ||
150 | /// Injection of syntax highlighting of doctests. | 150 | /// Injection of syntax highlighting of doctests. |
151 | pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, node: &SyntaxNode) { | 151 | pub(super) fn doc_comment( |
152 | let (owner, attributes, def) = match doc_attributes(sema, node) { | 152 | hl: &mut Highlights, |
153 | sema: &Semantics<RootDatabase>, | ||
154 | node: InFile<&SyntaxNode>, | ||
155 | ) { | ||
156 | let (owner, attributes, def) = match doc_attributes(sema, node.value) { | ||
153 | Some(it) => it, | 157 | Some(it) => it, |
154 | None => return, | 158 | None => return, |
155 | }; | 159 | }; |
@@ -157,7 +161,12 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n | |||
157 | let mut inj = Injector::default(); | 161 | let mut inj = Injector::default(); |
158 | inj.add_unmapped("fn doctest() {\n"); | 162 | inj.add_unmapped("fn doctest() {\n"); |
159 | 163 | ||
160 | let attrs_source_map = attributes.source_map(&owner); | 164 | let attrs_source_map = match def { |
165 | Definition::ModuleDef(hir::ModuleDef::Module(module)) => { | ||
166 | attributes.source_map_for_module(sema.db, module.into()) | ||
167 | } | ||
168 | _ => attributes.source_map(node.with_value(&owner)), | ||
169 | }; | ||
161 | 170 | ||
162 | let mut is_codeblock = false; | 171 | let mut is_codeblock = false; |
163 | let mut is_doctest = false; | 172 | let mut is_doctest = false; |
@@ -168,7 +177,10 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n | |||
168 | let mut intra_doc_links = Vec::new(); | 177 | let mut intra_doc_links = Vec::new(); |
169 | let mut string; | 178 | let mut string; |
170 | for attr in attributes.by_key("doc").attrs() { | 179 | for attr in attributes.by_key("doc").attrs() { |
171 | let src = attrs_source_map.source_of(&attr); | 180 | let InFile { file_id, value: src } = attrs_source_map.source_of(&attr); |
181 | if file_id != node.file_id { | ||
182 | continue; | ||
183 | } | ||
172 | let (line, range, prefix) = match &src { | 184 | let (line, range, prefix) = match &src { |
173 | Either::Left(it) => { | 185 | Either::Left(it) => { |
174 | string = match find_doc_string_in_attr(attr, it) { | 186 | string = match find_doc_string_in_attr(attr, it) { |
@@ -213,13 +225,16 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n | |||
213 | intra_doc_links.extend( | 225 | intra_doc_links.extend( |
214 | extract_definitions_from_markdown(line) | 226 | extract_definitions_from_markdown(line) |
215 | .into_iter() | 227 | .into_iter() |
216 | .filter(|(link, ns, _)| { | 228 | .filter_map(|(link, ns, range)| { |
217 | validate_intra_doc_link(sema.db, &def, link, *ns) | 229 | validate_intra_doc_link(sema.db, &def, &link, ns).zip(Some(range)) |
218 | }) | 230 | }) |
219 | .map(|(.., Range { start, end })| { | 231 | .map(|(def, Range { start, end })| { |
220 | TextRange::at( | 232 | ( |
221 | prev_range_start + TextSize::from(start as u32), | 233 | def, |
222 | TextSize::from((end - start) as u32), | 234 | TextRange::at( |
235 | prev_range_start + TextSize::from(start as u32), | ||
236 | TextSize::from((end - start) as u32), | ||
237 | ), | ||
223 | ) | 238 | ) |
224 | }), | 239 | }), |
225 | ); | 240 | ); |
@@ -243,10 +258,13 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n | |||
243 | } | 258 | } |
244 | } | 259 | } |
245 | 260 | ||
246 | for range in intra_doc_links { | 261 | for (def, range) in intra_doc_links { |
247 | hl.add(HlRange { | 262 | hl.add(HlRange { |
248 | range, | 263 | range, |
249 | highlight: HlTag::IntraDocLink | HlMod::Documentation, | 264 | highlight: module_def_to_hl_tag(def) |
265 | | HlMod::Documentation | ||
266 | | HlMod::Injected | ||
267 | | HlMod::IntraDocLink, | ||
250 | binding_hash: None, | 268 | binding_hash: None, |
251 | }); | 269 | }); |
252 | } | 270 | } |
@@ -305,7 +323,7 @@ fn validate_intra_doc_link( | |||
305 | def: &Definition, | 323 | def: &Definition, |
306 | link: &str, | 324 | link: &str, |
307 | ns: Option<hir::Namespace>, | 325 | ns: Option<hir::Namespace>, |
308 | ) -> bool { | 326 | ) -> Option<hir::ModuleDef> { |
309 | match def { | 327 | match def { |
310 | Definition::ModuleDef(def) => match def { | 328 | Definition::ModuleDef(def) => match def { |
311 | hir::ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns), | 329 | hir::ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns), |
@@ -325,5 +343,21 @@ fn validate_intra_doc_link( | |||
325 | | Definition::GenericParam(_) | 343 | | Definition::GenericParam(_) |
326 | | Definition::Label(_) => None, | 344 | | Definition::Label(_) => None, |
327 | } | 345 | } |
328 | .is_some() | 346 | } |
347 | |||
348 | fn module_def_to_hl_tag(def: hir::ModuleDef) -> HlTag { | ||
349 | let symbol = match def { | ||
350 | hir::ModuleDef::Module(_) => SymbolKind::Module, | ||
351 | hir::ModuleDef::Function(_) => SymbolKind::Function, | ||
352 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct, | ||
353 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum, | ||
354 | hir::ModuleDef::Adt(hir::Adt::Union(_)) => SymbolKind::Union, | ||
355 | hir::ModuleDef::Variant(_) => SymbolKind::Variant, | ||
356 | hir::ModuleDef::Const(_) => SymbolKind::Const, | ||
357 | hir::ModuleDef::Static(_) => SymbolKind::Static, | ||
358 | hir::ModuleDef::Trait(_) => SymbolKind::Trait, | ||
359 | hir::ModuleDef::TypeAlias(_) => SymbolKind::TypeAlias, | ||
360 | hir::ModuleDef::BuiltinType(_) => return HlTag::BuiltinType, | ||
361 | }; | ||
362 | HlTag::Symbol(symbol) | ||
329 | } | 363 | } |