diff options
author | Aleksey Kladov <[email protected]> | 2018-08-10 20:33:29 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-10 20:33:29 +0100 |
commit | 7c67612b8a894187fa3b64725531a5459f9211bf (patch) | |
tree | 9e2a536efa0c880d921fd8d4d74423afc9451fd4 /libeditor/src/lib.rs | |
parent | 26262aaf05983c5b7f41cc438e287523268fe1eb (diff) |
organizize
Diffstat (limited to 'libeditor/src/lib.rs')
-rw-r--r-- | libeditor/src/lib.rs | 155 |
1 files changed, 0 insertions, 155 deletions
diff --git a/libeditor/src/lib.rs b/libeditor/src/lib.rs deleted file mode 100644 index f77647338..000000000 --- a/libeditor/src/lib.rs +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | extern crate libsyntax2; | ||
2 | extern crate superslice; | ||
3 | |||
4 | mod extend_selection; | ||
5 | mod line_index; | ||
6 | |||
7 | use libsyntax2::{ | ||
8 | SyntaxNodeRef, AstNode, | ||
9 | algo::walk, | ||
10 | SyntaxKind::*, | ||
11 | }; | ||
12 | pub use libsyntax2::{TextRange, TextUnit, ast}; | ||
13 | pub use self::line_index::{LineIndex, LineCol}; | ||
14 | |||
15 | #[derive(Debug)] | ||
16 | pub struct HighlightedRange { | ||
17 | pub range: TextRange, | ||
18 | pub tag: &'static str, | ||
19 | } | ||
20 | |||
21 | #[derive(Debug)] | ||
22 | pub struct Diagnostic { | ||
23 | pub range: TextRange, | ||
24 | pub msg: String, | ||
25 | } | ||
26 | |||
27 | #[derive(Debug)] | ||
28 | pub struct Symbol { | ||
29 | // pub parent: ???, | ||
30 | pub name: String, | ||
31 | pub range: TextRange, | ||
32 | } | ||
33 | |||
34 | #[derive(Debug)] | ||
35 | pub struct Runnable { | ||
36 | pub range: TextRange, | ||
37 | pub kind: RunnableKind, | ||
38 | } | ||
39 | |||
40 | #[derive(Debug)] | ||
41 | pub enum RunnableKind { | ||
42 | Test { name: String }, | ||
43 | Bin, | ||
44 | } | ||
45 | |||
46 | pub fn highlight(file: &ast::File) -> Vec<HighlightedRange> { | ||
47 | let syntax = file.syntax(); | ||
48 | let mut res = Vec::new(); | ||
49 | for node in walk::preorder(syntax.as_ref()) { | ||
50 | let tag = match node.kind() { | ||
51 | ERROR => "error", | ||
52 | COMMENT | DOC_COMMENT => "comment", | ||
53 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", | ||
54 | ATTR => "attribute", | ||
55 | NAME_REF => "text", | ||
56 | NAME => "function", | ||
57 | INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal", | ||
58 | LIFETIME => "parameter", | ||
59 | k if k.is_keyword() => "keyword", | ||
60 | _ => continue, | ||
61 | }; | ||
62 | res.push(HighlightedRange { | ||
63 | range: node.range(), | ||
64 | tag, | ||
65 | }) | ||
66 | } | ||
67 | res | ||
68 | } | ||
69 | |||
70 | pub fn diagnostics(file: &ast::File) -> Vec<Diagnostic> { | ||
71 | let syntax = file.syntax(); | ||
72 | let mut res = Vec::new(); | ||
73 | |||
74 | for node in walk::preorder(syntax.as_ref()) { | ||
75 | if node.kind() == ERROR { | ||
76 | res.push(Diagnostic { | ||
77 | range: node.range(), | ||
78 | msg: "Syntax Error".to_string(), | ||
79 | }); | ||
80 | } | ||
81 | } | ||
82 | res.extend(file.errors().into_iter().map(|err| Diagnostic { | ||
83 | range: TextRange::offset_len(err.offset, 1.into()), | ||
84 | msg: err.msg, | ||
85 | })); | ||
86 | res | ||
87 | } | ||
88 | |||
89 | pub fn syntax_tree(file: &ast::File) -> String { | ||
90 | ::libsyntax2::utils::dump_tree(&file.syntax()) | ||
91 | } | ||
92 | |||
93 | pub fn symbols(file: &ast::File) -> Vec<Symbol> { | ||
94 | let syntax = file.syntax(); | ||
95 | let res: Vec<Symbol> = walk::preorder(syntax.as_ref()) | ||
96 | .filter_map(Declaration::cast) | ||
97 | .filter_map(|decl| { | ||
98 | let name = decl.name()?; | ||
99 | let range = decl.range(); | ||
100 | Some(Symbol { name, range }) | ||
101 | }) | ||
102 | .collect(); | ||
103 | res // NLL :-( | ||
104 | } | ||
105 | |||
106 | pub fn extend_selection(file: &ast::File, range: TextRange) -> Option<TextRange> { | ||
107 | let syntax = file.syntax(); | ||
108 | extend_selection::extend_selection(syntax.as_ref(), range) | ||
109 | } | ||
110 | |||
111 | pub fn runnables(file: &ast::File) -> Vec<Runnable> { | ||
112 | file | ||
113 | .functions() | ||
114 | .filter_map(|f| { | ||
115 | let name = f.name()?.text(); | ||
116 | let kind = if name == "main" { | ||
117 | RunnableKind::Bin | ||
118 | } else if f.has_atom_attr("test") { | ||
119 | RunnableKind::Test { | ||
120 | name: name.to_string() | ||
121 | } | ||
122 | } else { | ||
123 | return None; | ||
124 | }; | ||
125 | Some(Runnable { | ||
126 | range: f.syntax().range(), | ||
127 | kind, | ||
128 | }) | ||
129 | }) | ||
130 | .collect() | ||
131 | } | ||
132 | |||
133 | |||
134 | struct Declaration<'f> (SyntaxNodeRef<'f>); | ||
135 | |||
136 | impl<'f> Declaration<'f> { | ||
137 | fn cast(node: SyntaxNodeRef<'f>) -> Option<Declaration<'f>> { | ||
138 | match node.kind() { | ||
139 | | STRUCT_ITEM | ENUM_ITEM | FUNCTION | TRAIT_ITEM | ||
140 | | CONST_ITEM | STATIC_ITEM | MOD_ITEM | NAMED_FIELD | ||
141 | | TYPE_ITEM => Some(Declaration(node)), | ||
142 | _ => None | ||
143 | } | ||
144 | } | ||
145 | |||
146 | fn name(&self) -> Option<String> { | ||
147 | let name = self.0.children() | ||
148 | .find(|child| child.kind() == NAME)?; | ||
149 | Some(name.text()) | ||
150 | } | ||
151 | |||
152 | fn range(&self) -> TextRange { | ||
153 | self.0.range() | ||
154 | } | ||
155 | } | ||