aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src')
-rw-r--r--crates/ide/src/lib.rs6
-rw-r--r--crates/ide/src/syntax_highlighting.rs10
-rw-r--r--crates/ide/src/syntax_highlighting/format.rs4
-rw-r--r--crates/ide/src/syntax_highlighting/highlights.rs61
-rw-r--r--crates/ide/src/syntax_highlighting/injection.rs22
-rw-r--r--crates/ide/src/syntax_highlighting/macro_rules.rs6
6 files changed, 46 insertions, 63 deletions
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 674c72c23..409507bd0 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -77,7 +77,7 @@ pub use crate::{
77 runnables::{Runnable, RunnableKind, TestId}, 77 runnables::{Runnable, RunnableKind, TestId},
78 syntax_highlighting::{ 78 syntax_highlighting::{
79 tags::{Highlight, HlMod, HlMods, HlTag}, 79 tags::{Highlight, HlMod, HlMods, HlTag},
80 HighlightedRange, 80 HlRange,
81 }, 81 },
82}; 82};
83pub use assists::{Assist, AssistConfig, AssistId, AssistKind, InsertUseConfig}; 83pub use assists::{Assist, AssistConfig, AssistId, AssistKind, InsertUseConfig};
@@ -449,12 +449,12 @@ impl Analysis {
449 } 449 }
450 450
451 /// Computes syntax highlighting for the given file 451 /// Computes syntax highlighting for the given file
452 pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> { 452 pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HlRange>> {
453 self.with_db(|db| syntax_highlighting::highlight(db, file_id, None, false)) 453 self.with_db(|db| syntax_highlighting::highlight(db, file_id, None, false))
454 } 454 }
455 455
456 /// Computes syntax highlighting for the given file range. 456 /// Computes syntax highlighting for the given file range.
457 pub fn highlight_range(&self, frange: FileRange) -> Cancelable<Vec<HighlightedRange>> { 457 pub fn highlight_range(&self, frange: FileRange) -> Cancelable<Vec<HlRange>> {
458 self.with_db(|db| { 458 self.with_db(|db| {
459 syntax_highlighting::highlight(db, frange.file_id, Some(frange.range), false) 459 syntax_highlighting::highlight(db, frange.file_id, Some(frange.range), false)
460 }) 460 })
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 086c1245e..8bb7acb82 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -34,7 +34,7 @@ use crate::{
34pub(crate) use html::highlight_as_html; 34pub(crate) use html::highlight_as_html;
35 35
36#[derive(Debug, Clone)] 36#[derive(Debug, Clone)]
37pub struct HighlightedRange { 37pub struct HlRange {
38 pub range: TextRange, 38 pub range: TextRange,
39 pub highlight: Highlight, 39 pub highlight: Highlight,
40 pub binding_hash: Option<u64>, 40 pub binding_hash: Option<u64>,
@@ -54,7 +54,7 @@ pub(crate) fn highlight(
54 file_id: FileId, 54 file_id: FileId,
55 range_to_highlight: Option<TextRange>, 55 range_to_highlight: Option<TextRange>,
56 syntactic_name_ref_highlighting: bool, 56 syntactic_name_ref_highlighting: bool,
57) -> Vec<HighlightedRange> { 57) -> Vec<HlRange> {
58 let _p = profile::span("highlight"); 58 let _p = profile::span("highlight");
59 let sema = Semantics::new(db); 59 let sema = Semantics::new(db);
60 60
@@ -98,7 +98,7 @@ pub(crate) fn highlight(
98 match event.clone().map(|it| it.into_node().and_then(ast::MacroCall::cast)) { 98 match event.clone().map(|it| it.into_node().and_then(ast::MacroCall::cast)) {
99 WalkEvent::Enter(Some(mc)) => { 99 WalkEvent::Enter(Some(mc)) => {
100 if let Some(range) = macro_call_range(&mc) { 100 if let Some(range) = macro_call_range(&mc) {
101 stack.add(HighlightedRange { 101 stack.add(HlRange {
102 range, 102 range,
103 highlight: HlTag::Symbol(SymbolKind::Macro).into(), 103 highlight: HlTag::Symbol(SymbolKind::Macro).into(),
104 binding_hash: None, 104 binding_hash: None,
@@ -198,7 +198,7 @@ pub(crate) fn highlight(
198 } 198 }
199 199
200 if macro_rules_highlighter.highlight(element_to_highlight.clone()).is_none() { 200 if macro_rules_highlighter.highlight(element_to_highlight.clone()).is_none() {
201 stack.add(HighlightedRange { range, highlight, binding_hash }); 201 stack.add(HlRange { range, highlight, binding_hash });
202 } 202 }
203 203
204 if let Some(string) = 204 if let Some(string) =
@@ -209,7 +209,7 @@ pub(crate) fn highlight(
209 if let Some(char_ranges) = string.char_ranges() { 209 if let Some(char_ranges) = string.char_ranges() {
210 for (piece_range, _) in char_ranges.iter().filter(|(_, char)| char.is_ok()) { 210 for (piece_range, _) in char_ranges.iter().filter(|(_, char)| char.is_ok()) {
211 if string.text()[piece_range.start().into()..].starts_with('\\') { 211 if string.text()[piece_range.start().into()..].starts_with('\\') {
212 stack.add(HighlightedRange { 212 stack.add(HlRange {
213 range: piece_range + range.start(), 213 range: piece_range + range.start(),
214 highlight: HlTag::EscapeSequence.into(), 214 highlight: HlTag::EscapeSequence.into(),
215 binding_hash: None, 215 binding_hash: None,
diff --git a/crates/ide/src/syntax_highlighting/format.rs b/crates/ide/src/syntax_highlighting/format.rs
index 94cecd97f..d807ad0ad 100644
--- a/crates/ide/src/syntax_highlighting/format.rs
+++ b/crates/ide/src/syntax_highlighting/format.rs
@@ -4,7 +4,7 @@ use syntax::{
4 AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, 4 AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange,
5}; 5};
6 6
7use crate::{HighlightedRange, HlTag, SymbolKind}; 7use crate::{HlRange, HlTag, SymbolKind};
8 8
9use super::highlights::Highlights; 9use super::highlights::Highlights;
10 10
@@ -46,7 +46,7 @@ impl FormatStringHighlighter {
46 if self.format_string.as_ref() == Some(&SyntaxElement::from(string.syntax().clone())) { 46 if self.format_string.as_ref() == Some(&SyntaxElement::from(string.syntax().clone())) {
47 string.lex_format_specifier(|piece_range, kind| { 47 string.lex_format_specifier(|piece_range, kind| {
48 if let Some(highlight) = highlight_format_specifier(kind) { 48 if let Some(highlight) = highlight_format_specifier(kind) {
49 stack.add(HighlightedRange { 49 stack.add(HlRange {
50 range: piece_range + range.start(), 50 range: piece_range + range.start(),
51 highlight: highlight.into(), 51 highlight: highlight.into(),
52 binding_hash: None, 52 binding_hash: None,
diff --git a/crates/ide/src/syntax_highlighting/highlights.rs b/crates/ide/src/syntax_highlighting/highlights.rs
index f52076509..11c11ed28 100644
--- a/crates/ide/src/syntax_highlighting/highlights.rs
+++ b/crates/ide/src/syntax_highlighting/highlights.rs
@@ -4,33 +4,29 @@ use std::{cmp::Ordering, iter};
4use stdx::equal_range_by; 4use stdx::equal_range_by;
5use syntax::TextRange; 5use syntax::TextRange;
6 6
7use crate::{HighlightedRange, HlTag}; 7use crate::{HlRange, HlTag};
8 8
9pub(super) struct Highlights { 9pub(super) struct Highlights {
10 root: Node, 10 root: Node,
11} 11}
12 12
13struct Node { 13struct Node {
14 highlighted_range: HighlightedRange, 14 hl_range: HlRange,
15 nested: Vec<Node>, 15 nested: Vec<Node>,
16} 16}
17 17
18impl Highlights { 18impl Highlights {
19 pub(super) fn new(range: TextRange) -> Highlights { 19 pub(super) fn new(range: TextRange) -> Highlights {
20 Highlights { 20 Highlights {
21 root: Node::new(HighlightedRange { 21 root: Node::new(HlRange { range, highlight: HlTag::None.into(), binding_hash: None }),
22 range,
23 highlight: HlTag::None.into(),
24 binding_hash: None,
25 }),
26 } 22 }
27 } 23 }
28 24
29 pub(super) fn add(&mut self, highlighted_range: HighlightedRange) { 25 pub(super) fn add(&mut self, hl_range: HlRange) {
30 self.root.add(highlighted_range); 26 self.root.add(hl_range);
31 } 27 }
32 28
33 pub(super) fn to_vec(self) -> Vec<HighlightedRange> { 29 pub(super) fn to_vec(self) -> Vec<HlRange> {
34 let mut res = Vec::new(); 30 let mut res = Vec::new();
35 self.root.flatten(&mut res); 31 self.root.flatten(&mut res);
36 res 32 res
@@ -38,59 +34,54 @@ impl Highlights {
38} 34}
39 35
40impl Node { 36impl Node {
41 fn new(highlighted_range: HighlightedRange) -> Node { 37 fn new(hl_range: HlRange) -> Node {
42 Node { highlighted_range, nested: Vec::new() } 38 Node { hl_range, nested: Vec::new() }
43 } 39 }
44 40
45 fn add(&mut self, highlighted_range: HighlightedRange) { 41 fn add(&mut self, hl_range: HlRange) {
46 assert!(self.highlighted_range.range.contains_range(highlighted_range.range)); 42 assert!(self.hl_range.range.contains_range(hl_range.range));
47 43
48 // Fast path 44 // Fast path
49 if let Some(last) = self.nested.last_mut() { 45 if let Some(last) = self.nested.last_mut() {
50 if last.highlighted_range.range.contains_range(highlighted_range.range) { 46 if last.hl_range.range.contains_range(hl_range.range) {
51 return last.add(highlighted_range); 47 return last.add(hl_range);
52 } 48 }
53 if last.highlighted_range.range.end() <= highlighted_range.range.start() { 49 if last.hl_range.range.end() <= hl_range.range.start() {
54 return self.nested.push(Node::new(highlighted_range)); 50 return self.nested.push(Node::new(hl_range));
55 } 51 }
56 } 52 }
57 53
58 let (start, len) = equal_range_by(&self.nested, |n| { 54 let (start, len) =
59 ordering(n.highlighted_range.range, highlighted_range.range) 55 equal_range_by(&self.nested, |n| ordering(n.hl_range.range, hl_range.range));
60 });
61 56
62 if len == 1 57 if len == 1 && self.nested[start].hl_range.range.contains_range(hl_range.range) {
63 && self.nested[start].highlighted_range.range.contains_range(highlighted_range.range) 58 return self.nested[start].add(hl_range);
64 {
65 return self.nested[start].add(highlighted_range);
66 } 59 }
67 60
68 let nested = self 61 let nested = self
69 .nested 62 .nested
70 .splice(start..start + len, iter::once(Node::new(highlighted_range))) 63 .splice(start..start + len, iter::once(Node::new(hl_range)))
71 .collect::<Vec<_>>(); 64 .collect::<Vec<_>>();
72 self.nested[start].nested = nested; 65 self.nested[start].nested = nested;
73 } 66 }
74 67
75 fn flatten(&self, acc: &mut Vec<HighlightedRange>) { 68 fn flatten(&self, acc: &mut Vec<HlRange>) {
76 let mut start = self.highlighted_range.range.start(); 69 let mut start = self.hl_range.range.start();
77 let mut nested = self.nested.iter(); 70 let mut nested = self.nested.iter();
78 loop { 71 loop {
79 let next = nested.next(); 72 let next = nested.next();
80 let end = next.map_or(self.highlighted_range.range.end(), |it| { 73 let end = next.map_or(self.hl_range.range.end(), |it| it.hl_range.range.start());
81 it.highlighted_range.range.start()
82 });
83 if start < end { 74 if start < end {
84 acc.push(HighlightedRange { 75 acc.push(HlRange {
85 range: TextRange::new(start, end), 76 range: TextRange::new(start, end),
86 highlight: self.highlighted_range.highlight, 77 highlight: self.hl_range.highlight,
87 binding_hash: self.highlighted_range.binding_hash, 78 binding_hash: self.hl_range.binding_hash,
88 }); 79 });
89 } 80 }
90 start = match next { 81 start = match next {
91 Some(child) => { 82 Some(child) => {
92 child.flatten(acc); 83 child.flatten(acc);
93 child.highlighted_range.range.end() 84 child.hl_range.range.end()
94 } 85 }
95 None => break, 86 None => break,
96 } 87 }
diff --git a/crates/ide/src/syntax_highlighting/injection.rs b/crates/ide/src/syntax_highlighting/injection.rs
index a6941234e..13dde1dc4 100644
--- a/crates/ide/src/syntax_highlighting/injection.rs
+++ b/crates/ide/src/syntax_highlighting/injection.rs
@@ -7,7 +7,7 @@ use ide_db::call_info::ActiveParameter;
7use itertools::Itertools; 7use itertools::Itertools;
8use syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; 8use syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize};
9 9
10use crate::{Analysis, HighlightedRange, HlMod, HlTag, RootDatabase}; 10use crate::{Analysis, HlMod, HlRange, HlTag, RootDatabase};
11 11
12use super::{highlights::Highlights, injector::Injector}; 12use super::{highlights::Highlights, injector::Injector};
13 13
@@ -26,11 +26,7 @@ pub(super) fn highlight_injection(
26 let (analysis, tmp_file_id) = Analysis::from_single_file(marker_info.cleaned_text.clone()); 26 let (analysis, tmp_file_id) = Analysis::from_single_file(marker_info.cleaned_text.clone());
27 27
28 if let Some(range) = literal.open_quote_text_range() { 28 if let Some(range) = literal.open_quote_text_range() {
29 acc.add(HighlightedRange { 29 acc.add(HlRange { range, highlight: HlTag::StringLiteral.into(), binding_hash: None })
30 range,
31 highlight: HlTag::StringLiteral.into(),
32 binding_hash: None,
33 })
34 } 30 }
35 31
36 for mut h in analysis.highlight(tmp_file_id).unwrap() { 32 for mut h in analysis.highlight(tmp_file_id).unwrap() {
@@ -42,11 +38,7 @@ pub(super) fn highlight_injection(
42 } 38 }
43 39
44 if let Some(range) = literal.close_quote_text_range() { 40 if let Some(range) = literal.close_quote_text_range() {
45 acc.add(HighlightedRange { 41 acc.add(HlRange { range, highlight: HlTag::StringLiteral.into(), binding_hash: None })
46 range,
47 highlight: HlTag::StringLiteral.into(),
48 binding_hash: None,
49 })
50 } 42 }
51 43
52 Some(()) 44 Some(())
@@ -116,7 +108,7 @@ const RUSTDOC_FENCE_TOKENS: &[&'static str] = &[
116/// Lastly, a vector of new comment highlight ranges (spanning only the 108/// Lastly, a vector of new comment highlight ranges (spanning only the
117/// comment prefix) is returned which is used in the syntax highlighting 109/// comment prefix) is returned which is used in the syntax highlighting
118/// injection to replace the previous (line-spanning) comment ranges. 110/// injection to replace the previous (line-spanning) comment ranges.
119pub(super) fn extract_doc_comments(node: &SyntaxNode) -> Option<(Vec<HighlightedRange>, Injector)> { 111pub(super) fn extract_doc_comments(node: &SyntaxNode) -> Option<(Vec<HlRange>, Injector)> {
120 let mut inj = Injector::default(); 112 let mut inj = Injector::default();
121 // wrap the doctest into function body to get correct syntax highlighting 113 // wrap the doctest into function body to get correct syntax highlighting
122 let prefix = "fn doctest() {\n"; 114 let prefix = "fn doctest() {\n";
@@ -166,7 +158,7 @@ pub(super) fn extract_doc_comments(node: &SyntaxNode) -> Option<(Vec<Highlighted
166 pos 158 pos
167 }; 159 };
168 160
169 new_comments.push(HighlightedRange { 161 new_comments.push(HlRange {
170 range: TextRange::new( 162 range: TextRange::new(
171 range.start(), 163 range.start(),
172 range.start() + TextSize::try_from(pos).unwrap(), 164 range.start() + TextSize::try_from(pos).unwrap(),
@@ -196,7 +188,7 @@ pub(super) fn extract_doc_comments(node: &SyntaxNode) -> Option<(Vec<Highlighted
196 188
197/// Injection of syntax highlighting of doctests. 189/// Injection of syntax highlighting of doctests.
198pub(super) fn highlight_doc_comment( 190pub(super) fn highlight_doc_comment(
199 new_comments: Vec<HighlightedRange>, 191 new_comments: Vec<HlRange>,
200 inj: Injector, 192 inj: Injector,
201 stack: &mut Highlights, 193 stack: &mut Highlights,
202) { 194) {
@@ -207,7 +199,7 @@ pub(super) fn highlight_doc_comment(
207 199
208 for h in analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)).unwrap() { 200 for h in analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)).unwrap() {
209 for r in inj.map_range_up(h.range) { 201 for r in inj.map_range_up(h.range) {
210 stack.add(HighlightedRange { 202 stack.add(HlRange {
211 range: r, 203 range: r,
212 highlight: h.highlight | HlMod::Injected, 204 highlight: h.highlight | HlMod::Injected,
213 binding_hash: h.binding_hash, 205 binding_hash: h.binding_hash,
diff --git a/crates/ide/src/syntax_highlighting/macro_rules.rs b/crates/ide/src/syntax_highlighting/macro_rules.rs
index 71dd1ccc5..21d8a9835 100644
--- a/crates/ide/src/syntax_highlighting/macro_rules.rs
+++ b/crates/ide/src/syntax_highlighting/macro_rules.rs
@@ -1,7 +1,7 @@
1//! Syntax highlighting for macro_rules!. 1//! Syntax highlighting for macro_rules!.
2use syntax::{SyntaxElement, SyntaxKind, SyntaxToken, TextRange, T}; 2use syntax::{SyntaxElement, SyntaxKind, SyntaxToken, TextRange, T};
3 3
4use crate::{HighlightedRange, HlTag}; 4use crate::{HlRange, HlTag};
5 5
6#[derive(Default)] 6#[derive(Default)]
7pub(super) struct MacroRulesHighlighter { 7pub(super) struct MacroRulesHighlighter {
@@ -19,11 +19,11 @@ impl MacroRulesHighlighter {
19 } 19 }
20 } 20 }
21 21
22 pub(super) fn highlight(&self, element: SyntaxElement) -> Option<HighlightedRange> { 22 pub(super) fn highlight(&self, element: SyntaxElement) -> Option<HlRange> {
23 if let Some(state) = self.state.as_ref() { 23 if let Some(state) = self.state.as_ref() {
24 if matches!(state.rule_state, RuleState::Matcher | RuleState::Expander) { 24 if matches!(state.rule_state, RuleState::Matcher | RuleState::Expander) {
25 if let Some(range) = is_metavariable(element) { 25 if let Some(range) = is_metavariable(element) {
26 return Some(HighlightedRange { 26 return Some(HlRange {
27 range, 27 range,
28 highlight: HlTag::UnresolvedReference.into(), 28 highlight: HlTag::UnresolvedReference.into(),
29 binding_hash: None, 29 binding_hash: None,