From 80366e90f5c1b809c8902e42dced42c0dc9d92ac Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 5 Aug 2018 19:06:14 +0300 Subject: File symnols --- libeditor/src/lib.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'libeditor/src') diff --git a/libeditor/src/lib.rs b/libeditor/src/lib.rs index 119bdb2d6..091aed125 100644 --- a/libeditor/src/lib.rs +++ b/libeditor/src/lib.rs @@ -2,6 +2,7 @@ extern crate libsyntax2; extern crate text_unit; use libsyntax2::{ + SyntaxNodeRef, algo::walk, SyntaxKind::*, }; @@ -16,6 +17,13 @@ pub struct HighlightedRange { pub tag: &'static str, } +#[derive(Debug)] +pub struct Symbol { + // pub parent: ???, + pub name: String, + pub range: TextRange, +} + impl File { pub fn new(text: &str) -> File { File { @@ -41,7 +49,7 @@ impl File { }; res.push(HighlightedRange { range: node.range(), - tag + tag, }) } res @@ -50,4 +58,41 @@ impl File { pub fn syntax_tree(&self) -> String { ::libsyntax2::utils::dump_tree(&self.inner.syntax()) } + + pub fn symbols(&self) -> Vec { + let syntax = self.inner.syntax(); + let res: Vec = walk::preorder(syntax.as_ref()) + .filter_map(Declaration::cast) + .filter_map(|decl| { + let name = decl.name()?; + let range = decl.range(); + Some(Symbol { name, range }) + }) + .collect(); + res // NLL :-( + } +} + + +struct Declaration<'f>(SyntaxNodeRef<'f>); + +impl<'f> Declaration<'f> { + fn cast(node: SyntaxNodeRef<'f>) -> Option> { + match node.kind() { + | STRUCT_ITEM | ENUM_ITEM | FN_ITEM | TRAIT_ITEM + | CONST_ITEM | STATIC_ITEM | MOD_ITEM | NAMED_FIELD + | TYPE_ITEM => Some(Declaration(node)), + _ => None + } + } + + fn name(&self) -> Option { + let name = self.0.children() + .find(|child| child.kind() == NAME)?; + Some(name.text()) + } + + fn range(&self) -> TextRange { + self.0.range() + } } -- cgit v1.2.3