aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/syntax_highlighting.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/syntax_highlighting.rs')
-rw-r--r--crates/ra_ide_api/src/syntax_highlighting.rs25
1 files changed, 13 insertions, 12 deletions
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index eb392d5da..16a728789 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -31,8 +31,8 @@ fn is_control_keyword(kind: SyntaxKind) -> bool {
31 } 31 }
32} 32}
33 33
34fn is_variable_mutable(db: &RootDatabase, analyzer: &hir::SourceAnalyzer, pat: &ast::Pat) -> bool { 34fn is_variable_mutable(db: &RootDatabase, analyzer: &hir::SourceAnalyzer, pat: ast::Pat) -> bool {
35 let ty = analyzer.type_of_pat(db, pat).unwrap_or(Ty::Unknown); 35 let ty = analyzer.type_of_pat(db, &pat).unwrap_or(Ty::Unknown);
36 let is_ty_mut = { 36 let is_ty_mut = {
37 if let Some((_, mutability)) = ty.as_reference() { 37 if let Some((_, mutability)) = ty.as_reference() {
38 match mutability { 38 match mutability {
@@ -55,7 +55,7 @@ fn is_variable_mutable(db: &RootDatabase, analyzer: &hir::SourceAnalyzer, pat: &
55pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { 55pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
56 let _p = profile("highlight"); 56 let _p = profile("highlight");
57 let parse = db.parse(file_id); 57 let parse = db.parse(file_id);
58 let root = parse.tree().syntax(); 58 let root = parse.tree().syntax().clone();
59 59
60 fn calc_binding_hash(file_id: FileId, text: &SmolStr, shadow_count: u32) -> u64 { 60 fn calc_binding_hash(file_id: FileId, text: &SmolStr, shadow_count: u32) -> u64 {
61 fn hash<T: std::hash::Hash + std::fmt::Debug>(x: T) -> u64 { 61 fn hash<T: std::hash::Hash + std::fmt::Debug>(x: T) -> u64 {
@@ -70,6 +70,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
70 } 70 }
71 71
72 // Visited nodes to handle highlighting priorities 72 // Visited nodes to handle highlighting priorities
73 // FIXME: retain only ranges here
73 let mut highlighted: FxHashSet<SyntaxElement> = FxHashSet::default(); 74 let mut highlighted: FxHashSet<SyntaxElement> = FxHashSet::default();
74 let mut bindings_shadow_count: FxHashMap<SmolStr, u32> = FxHashMap::default(); 75 let mut bindings_shadow_count: FxHashMap<SmolStr, u32> = FxHashMap::default();
75 76
@@ -84,14 +85,14 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
84 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", 85 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string",
85 ATTR => "attribute", 86 ATTR => "attribute",
86 NAME_REF => { 87 NAME_REF => {
87 if let Some(name_ref) = node.as_node().and_then(ast::NameRef::cast) { 88 if let Some(name_ref) = node.as_node().cloned().and_then(ast::NameRef::cast) {
88 // FIXME: revisit this after #1340 89 // FIXME: revisit this after #1340
89 use crate::name_ref_kind::{classify_name_ref, NameRefKind::*}; 90 use crate::name_ref_kind::{classify_name_ref, NameRefKind::*};
90 use hir::{ImplItem, ModuleDef}; 91 use hir::{ImplItem, ModuleDef};
91 92
92 // FIXME: try to reuse the SourceAnalyzers 93 // FIXME: try to reuse the SourceAnalyzers
93 let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); 94 let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None);
94 match classify_name_ref(db, &analyzer, name_ref) { 95 match classify_name_ref(db, &analyzer, &name_ref) {
95 Some(Method(_)) => "function", 96 Some(Method(_)) => "function",
96 Some(Macro(_)) => "macro", 97 Some(Macro(_)) => "macro",
97 Some(FieldAccess(_)) => "field", 98 Some(FieldAccess(_)) => "field",
@@ -113,13 +114,13 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
113 Some(Pat(ptr)) => { 114 Some(Pat(ptr)) => {
114 binding_hash = Some({ 115 binding_hash = Some({
115 let text = 116 let text =
116 ptr.syntax_node_ptr().to_node(root).text().to_smol_string(); 117 ptr.syntax_node_ptr().to_node(&root).text().to_smol_string();
117 let shadow_count = 118 let shadow_count =
118 bindings_shadow_count.entry(text.clone()).or_default(); 119 bindings_shadow_count.entry(text.clone()).or_default();
119 calc_binding_hash(file_id, &text, *shadow_count) 120 calc_binding_hash(file_id, &text, *shadow_count)
120 }); 121 });
121 122
122 if is_variable_mutable(db, &analyzer, ptr.to_node(root)) { 123 if is_variable_mutable(db, &analyzer, ptr.to_node(&root)) {
123 "variable.mut" 124 "variable.mut"
124 } else { 125 } else {
125 "variable" 126 "variable"
@@ -134,7 +135,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
134 } 135 }
135 } 136 }
136 NAME => { 137 NAME => {
137 if let Some(name) = node.as_node().and_then(ast::Name::cast) { 138 if let Some(name) = node.as_node().cloned().and_then(ast::Name::cast) {
138 let analyzer = hir::SourceAnalyzer::new(db, file_id, name.syntax(), None); 139 let analyzer = hir::SourceAnalyzer::new(db, file_id, name.syntax(), None);
139 if let Some(pat) = name.syntax().ancestors().find_map(ast::Pat::cast) { 140 if let Some(pat) = name.syntax().ancestors().find_map(ast::Pat::cast) {
140 binding_hash = Some({ 141 binding_hash = Some({
@@ -176,12 +177,11 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
176 k if is_control_keyword(k) => "keyword.control", 177 k if is_control_keyword(k) => "keyword.control",
177 k if k.is_keyword() => "keyword", 178 k if k.is_keyword() => "keyword",
178 _ => { 179 _ => {
179 // let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); 180 if let Some(macro_call) = node.as_node().cloned().and_then(ast::MacroCall::cast) {
180 if let Some(macro_call) = node.as_node().and_then(ast::MacroCall::cast) {
181 if let Some(path) = macro_call.path() { 181 if let Some(path) = macro_call.path() {
182 if let Some(segment) = path.segment() { 182 if let Some(segment) = path.segment() {
183 if let Some(name_ref) = segment.name_ref() { 183 if let Some(name_ref) = segment.name_ref() {
184 highlighted.insert(name_ref.syntax().into()); 184 highlighted.insert(name_ref.syntax().clone().into());
185 let range_start = name_ref.syntax().range().start(); 185 let range_start = name_ref.syntax().range().start();
186 let mut range_end = name_ref.syntax().range().end(); 186 let mut range_end = name_ref.syntax().range().end();
187 for sibling in path.syntax().siblings_with_tokens(Direction::Next) { 187 for sibling in path.syntax().siblings_with_tokens(Direction::Next) {
@@ -230,7 +230,8 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
230 let mut buf = String::new(); 230 let mut buf = String::new();
231 buf.push_str(&STYLE); 231 buf.push_str(&STYLE);
232 buf.push_str("<pre><code>"); 232 buf.push_str("<pre><code>");
233 let tokens = parse.tree().syntax().descendants_with_tokens().filter_map(|it| it.as_token()); 233 let tokens =
234 parse.tree().syntax().descendants_with_tokens().filter_map(|it| it.as_token().cloned());
234 for token in tokens { 235 for token in tokens {
235 could_intersect.retain(|it| token.range().start() <= it.range.end()); 236 could_intersect.retain(|it| token.range().start() <= it.range.end());
236 while let Some(r) = ranges.get(frontier) { 237 while let Some(r) = ranges.get(frontier) {