From 8f6f864547bad3d2bb34ea0cf5a32e8adee58c4e Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Tue, 25 Feb 2020 08:38:50 -0500 Subject: Semantic Ranges --- crates/ra_ide/src/syntax_highlighting.rs | 49 ++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'crates/ra_ide/src/syntax_highlighting.rs') diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 812229b4e..22c84561f 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -5,8 +5,8 @@ use ra_db::SourceDatabase; use ra_ide_db::{defs::NameDefinition, RootDatabase}; use ra_prof::profile; use ra_syntax::{ - ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, SyntaxToken, TextRange, - WalkEvent, T, + ast, AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxKind::*, SyntaxToken, + TextRange, WalkEvent, T, }; use rustc_hash::FxHashMap; @@ -69,6 +69,16 @@ fn is_control_keyword(kind: SyntaxKind) -> bool { pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec { let _p = profile("highlight"); + highlight_range(db, file_id, None) +} + +pub(crate) fn highlight_range( + db: &RootDatabase, + file_id: FileId, + range: Option, +) -> Vec { + let _p = profile("highlight_range"); + let parse = db.parse(file_id); let root = parse.tree().syntax().clone(); @@ -79,6 +89,15 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec match root.covering_element(range) { + NodeOrToken::Node(node) => node, + NodeOrToken::Token(token) => token.parent(), + }, + None => root, + }; + for event in root.preorder_with_tokens() { match event { WalkEvent::Enter(node) => match node.kind() { @@ -374,7 +393,10 @@ mod tests { use test_utils::{assert_eq_text, project_dir, read_text}; - use crate::mock_analysis::{single_file, MockAnalysis}; + use crate::{ + mock_analysis::{single_file, MockAnalysis}, + FileRange, TextRange, + }; #[test] fn test_highlighting() { @@ -475,4 +497,25 @@ fn bar() { let _ = host.analysis().highlight(file_id).unwrap(); // eprintln!("elapsed: {:?}", t.elapsed()); } + + #[test] + fn test_ranges() { + let (analysis, file_id) = single_file( + r#" + #[derive(Clone, Debug)] + struct Foo { + pub x: i32, + pub y: i32, + }"#, + ); + + let highlights = &analysis + .highlight_range(FileRange { + file_id, + range: TextRange::offset_len(82.into(), 1.into()), // "x" + }) + .unwrap(); + + assert_eq!(highlights[0].tag, "field"); + } } -- cgit v1.2.3