From 7afd84febc76a75a3ed1be75c57ff35d7b8b3de6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 11 Aug 2018 12:28:59 +0300 Subject: visitor --- crates/libeditor/src/extend_selection.rs | 7 +++- crates/libeditor/src/lib.rs | 14 +++---- crates/libeditor/src/symbols.rs | 67 ++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 crates/libeditor/src/symbols.rs (limited to 'crates/libeditor/src') diff --git a/crates/libeditor/src/extend_selection.rs b/crates/libeditor/src/extend_selection.rs index 16d4bc084..ed7d9b3f7 100644 --- a/crates/libeditor/src/extend_selection.rs +++ b/crates/libeditor/src/extend_selection.rs @@ -1,11 +1,16 @@ use libsyntax2::{ + ast, AstNode, TextRange, SyntaxNodeRef, SyntaxKind::WHITESPACE, algo::{find_leaf_at_offset, find_covering_node, ancestors}, }; +pub fn extend_selection(file: &ast::File, range: TextRange) -> Option { + let syntax = file.syntax(); + extend(syntax.as_ref(), range) +} -pub(crate) fn extend_selection(root: SyntaxNodeRef, range: TextRange) -> Option { +pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option { if range.is_empty() { let offset = range.start(); let mut leaves = find_leaf_at_offset(root, offset); diff --git a/crates/libeditor/src/lib.rs b/crates/libeditor/src/lib.rs index 293fafae7..4ea344b17 100644 --- a/crates/libeditor/src/lib.rs +++ b/crates/libeditor/src/lib.rs @@ -2,16 +2,21 @@ extern crate libsyntax2; extern crate superslice; mod extend_selection; +mod symbols; mod line_index; use libsyntax2::{ - ast, + ast::{self, NameOwner}, SyntaxNodeRef, AstNode, algo::walk, SyntaxKind::*, }; pub use libsyntax2::{File, TextRange, TextUnit}; -pub use self::line_index::{LineIndex, LineCol}; +pub use self::{ + line_index::{LineIndex, LineCol}, + extend_selection::extend_selection, + symbols::{FileSymbol, file_symbols} +}; #[derive(Debug)] pub struct HighlightedRange { @@ -108,11 +113,6 @@ pub fn symbols(file: &ast::File) -> Vec { res // NLL :-( } -pub fn extend_selection(file: &ast::File, range: TextRange) -> Option { - let syntax = file.syntax(); - extend_selection::extend_selection(syntax.as_ref(), range) -} - pub fn runnables(file: &ast::File) -> Vec { file .functions() diff --git a/crates/libeditor/src/symbols.rs b/crates/libeditor/src/symbols.rs new file mode 100644 index 000000000..3faf96868 --- /dev/null +++ b/crates/libeditor/src/symbols.rs @@ -0,0 +1,67 @@ +use libsyntax2::{ + SyntaxKind, SyntaxNodeRef, SyntaxRoot, AstNode, + ast::{self, NameOwner}, + algo::{ + visit::{visitor, Visitor}, + walk::{walk, WalkEvent}, + }, +}; +use TextRange; + +#[derive(Debug)] +pub struct FileSymbol { + pub parent: Option, + pub name: String, + pub name_range: TextRange, + pub node_range: TextRange, + pub kind: SyntaxKind, +} + + +pub fn file_symbols(file: &ast::File) -> Vec { + let mut res = Vec::new(); + let mut stack = Vec::new(); + let syntax = file.syntax(); + + for event in walk(syntax.as_ref()) { + match event { + WalkEvent::Enter(node) => { + match to_symbol(node) { + Some(mut symbol) => { + symbol.parent = stack.last().map(|&n| n); + stack.push(res.len()); + res.push(symbol); + } + None => (), + } + } + WalkEvent::Exit(node) => { + if to_symbol(node).is_some() { + stack.pop().unwrap(); + } + } + } + } + res +} + +fn to_symbol(node: SyntaxNodeRef) -> Option { + fn decl<'a, N: NameOwner<&'a SyntaxRoot>>(node: N) -> Option { + let name = node.name()?; + Some(FileSymbol { + parent: None, + name: name.text(), + name_range: name.syntax().range(), + node_range: node.syntax().range(), + kind: node.syntax().kind(), + }) + } + + visitor() + .visit(decl::>) + .visit(decl::>) + .visit(decl::>) + .visit(decl::>) + .visit(decl::>) + .accept(node)? +} -- cgit v1.2.3