diff options
author | Aleksey Kladov <[email protected]> | 2018-07-30 19:58:49 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-07-30 19:58:49 +0100 |
commit | ac0d8c48f7a277d4a43448fe7dd4279383bc53f0 (patch) | |
tree | 5fe6d1f761f15d1e2d63fc4e9be0c16e2f0b3d93 /code/native | |
parent | 6fc66c4ee667da871ea1f0c8b48b5e9b7373a187 (diff) |
JS plugin
Diffstat (limited to 'code/native')
-rw-r--r-- | code/native/Cargo.toml | 19 | ||||
-rw-r--r-- | code/native/build.rs | 7 | ||||
-rw-r--r-- | code/native/src/lib.rs | 80 |
3 files changed, 106 insertions, 0 deletions
diff --git a/code/native/Cargo.toml b/code/native/Cargo.toml new file mode 100644 index 000000000..1648dfb33 --- /dev/null +++ b/code/native/Cargo.toml | |||
@@ -0,0 +1,19 @@ | |||
1 | [package] | ||
2 | name = "backend" | ||
3 | version = "0.1.0" | ||
4 | authors = ["Aleksey Kladov <[email protected]>"] | ||
5 | license = "MIT" | ||
6 | build = "build.rs" | ||
7 | exclude = ["artifacts.json", "index.node"] | ||
8 | [workspace] | ||
9 | |||
10 | [lib] | ||
11 | name = "backend" | ||
12 | crate-type = ["dylib"] | ||
13 | |||
14 | [build-dependencies] | ||
15 | neon-build = "0.2.0" | ||
16 | |||
17 | [dependencies] | ||
18 | neon = "0.2.0" | ||
19 | libsyntax2 = { path = "../../" } | ||
diff --git a/code/native/build.rs b/code/native/build.rs new file mode 100644 index 000000000..687a66194 --- /dev/null +++ b/code/native/build.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | extern crate neon_build; | ||
2 | |||
3 | fn main() { | ||
4 | neon_build::setup(); // must be called in build.rs | ||
5 | |||
6 | // add project-specific build logic here... | ||
7 | } | ||
diff --git a/code/native/src/lib.rs b/code/native/src/lib.rs new file mode 100644 index 000000000..dcf478cf5 --- /dev/null +++ b/code/native/src/lib.rs | |||
@@ -0,0 +1,80 @@ | |||
1 | #[macro_use] | ||
2 | extern crate neon; | ||
3 | extern crate libsyntax2; | ||
4 | |||
5 | use libsyntax2::{ | ||
6 | TextRange, | ||
7 | File, | ||
8 | utils::dump_tree, | ||
9 | SyntaxKind::*, | ||
10 | }; | ||
11 | use neon::prelude::*; | ||
12 | |||
13 | pub struct Wrapper { | ||
14 | inner: File, | ||
15 | } | ||
16 | |||
17 | impl Wrapper { | ||
18 | fn highlight(&self) -> Vec<(TextRange, &'static str)> { | ||
19 | let mut res = Vec::new(); | ||
20 | self.inner.for_each_node(|node| { | ||
21 | if node.kind() == ERROR { | ||
22 | res.push((node.range(), "error")) | ||
23 | } | ||
24 | }); | ||
25 | res | ||
26 | } | ||
27 | } | ||
28 | |||
29 | |||
30 | |||
31 | declare_types! { | ||
32 | /// A class for generating greeting strings. | ||
33 | pub class RustFile for Wrapper { | ||
34 | init(mut cx) { | ||
35 | let text = cx.argument::<JsString>(0)?.value(); | ||
36 | Ok(Wrapper { | ||
37 | inner: File::parse(&text) | ||
38 | }) | ||
39 | } | ||
40 | |||
41 | method syntaxTree(mut cx) { | ||
42 | let this = cx.this(); | ||
43 | let tree = { | ||
44 | let guard = cx.lock(); | ||
45 | let wrapper = this.borrow(&guard); | ||
46 | dump_tree(&wrapper.inner.syntax()) | ||
47 | }; | ||
48 | Ok(cx.string(tree.as_str()).upcast()) | ||
49 | } | ||
50 | |||
51 | method highlight(mut cx) { | ||
52 | let this = cx.this(); | ||
53 | let highlights = { | ||
54 | let guard = cx.lock(); | ||
55 | let wrapper = this.borrow(&guard); | ||
56 | wrapper.highlight() | ||
57 | }; | ||
58 | let res = cx.empty_array(); | ||
59 | for (i, (range, tag)) in highlights.into_iter().enumerate() { | ||
60 | let start: u32 = range.start().into(); | ||
61 | let end: u32 = range.end().into(); | ||
62 | let start = cx.number(start); | ||
63 | let end = cx.number(end); | ||
64 | let tag = cx.string(tag); | ||
65 | let hl = cx.empty_array(); | ||
66 | hl.set(&mut cx, 0, start)?; | ||
67 | hl.set(&mut cx, 1, end)?; | ||
68 | hl.set(&mut cx, 2, tag)?; | ||
69 | res.set(&mut cx, i as u32, hl)?; | ||
70 | } | ||
71 | |||
72 | Ok(res.upcast()) | ||
73 | } | ||
74 | } | ||
75 | |||
76 | } | ||
77 | |||
78 | register_module!(mut cx, { | ||
79 | cx.export_class::<RustFile>("RustFile") | ||
80 | }); | ||