aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/syntax_highlighting
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/syntax_highlighting')
-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
4 files changed, 38 insertions, 55 deletions
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,