diff options
author | Aleksey Kladov <[email protected]> | 2018-08-13 12:24:22 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-13 12:24:22 +0100 |
commit | ed2ac1713326df6b926062efcc6109a20cdf7c37 (patch) | |
tree | c1c75d09e2adbbd54190c5b6ce6efdb7ea251da3 /crates/libsyntax2/src | |
parent | 18486a02fae5966e61f16ea7bc5c33c6c7c69487 (diff) |
smol_str to a crate
Diffstat (limited to 'crates/libsyntax2/src')
-rw-r--r-- | crates/libsyntax2/src/ast/mod.rs | 9 | ||||
-rw-r--r-- | crates/libsyntax2/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/libsyntax2/src/smol_str.rs | 83 | ||||
-rw-r--r-- | crates/libsyntax2/src/yellow/green.rs | 17 | ||||
-rw-r--r-- | crates/libsyntax2/src/yellow/syntax.rs | 6 |
5 files changed, 27 insertions, 92 deletions
diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs index 56bc099fe..e9362d048 100644 --- a/crates/libsyntax2/src/ast/mod.rs +++ b/crates/libsyntax2/src/ast/mod.rs | |||
@@ -1,6 +1,9 @@ | |||
1 | mod generated; | 1 | mod generated; |
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | |||
5 | use smol_str::SmolStr; | ||
6 | |||
4 | use { | 7 | use { |
5 | SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError, | 8 | SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError, |
6 | SyntaxKind::*, | 9 | SyntaxKind::*, |
@@ -64,7 +67,9 @@ impl<R: TreeRoot> Function<R> { | |||
64 | } | 67 | } |
65 | 68 | ||
66 | impl<R: TreeRoot> Name<R> { | 69 | impl<R: TreeRoot> Name<R> { |
67 | pub fn text(&self) -> String { | 70 | pub fn text(&self) -> SmolStr { |
68 | self.syntax().text() | 71 | let ident = self.syntax().first_child() |
72 | .unwrap(); | ||
73 | ident.leaf_text().unwrap() | ||
69 | } | 74 | } |
70 | } | 75 | } |
diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index ca33618a0..feef542c4 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs | |||
@@ -21,10 +21,11 @@ | |||
21 | //#![warn(unreachable_pub)] // rust-lang/rust#47816 | 21 | //#![warn(unreachable_pub)] // rust-lang/rust#47816 |
22 | 22 | ||
23 | extern crate itertools; | 23 | extern crate itertools; |
24 | extern crate text_unit; | ||
25 | extern crate unicode_xid; | 24 | extern crate unicode_xid; |
26 | extern crate drop_bomb; | 25 | extern crate drop_bomb; |
27 | extern crate parking_lot; | 26 | extern crate parking_lot; |
27 | extern crate smol_str; | ||
28 | extern crate text_unit; | ||
28 | 29 | ||
29 | pub mod algo; | 30 | pub mod algo; |
30 | pub mod ast; | 31 | pub mod ast; |
@@ -35,7 +36,6 @@ mod grammar; | |||
35 | mod parser_impl; | 36 | mod parser_impl; |
36 | 37 | ||
37 | mod syntax_kinds; | 38 | mod syntax_kinds; |
38 | mod smol_str; | ||
39 | mod yellow; | 39 | mod yellow; |
40 | /// Utilities for simple uses of the parser. | 40 | /// Utilities for simple uses of the parser. |
41 | pub mod utils; | 41 | pub mod utils; |
diff --git a/crates/libsyntax2/src/smol_str.rs b/crates/libsyntax2/src/smol_str.rs deleted file mode 100644 index abf69dce7..000000000 --- a/crates/libsyntax2/src/smol_str.rs +++ /dev/null | |||
@@ -1,83 +0,0 @@ | |||
1 | use std::{sync::Arc}; | ||
2 | |||
3 | const INLINE_CAP: usize = 22; | ||
4 | const WS_TAG: u8 = (INLINE_CAP + 1) as u8; | ||
5 | |||
6 | #[derive(Clone, Debug)] | ||
7 | pub(crate) enum SmolStr { | ||
8 | Heap(Arc<str>), | ||
9 | Inline { | ||
10 | len: u8, | ||
11 | buf: [u8; INLINE_CAP], | ||
12 | }, | ||
13 | } | ||
14 | |||
15 | impl SmolStr { | ||
16 | pub fn new(text: &str) -> SmolStr { | ||
17 | let len = text.len(); | ||
18 | if len <= INLINE_CAP { | ||
19 | let mut buf = [0; INLINE_CAP]; | ||
20 | buf[..len].copy_from_slice(text.as_bytes()); | ||
21 | return SmolStr::Inline { len: len as u8, buf }; | ||
22 | } | ||
23 | |||
24 | let newlines = text.bytes().take_while(|&b| b == b'\n').count(); | ||
25 | let spaces = text[newlines..].bytes().take_while(|&b| b == b' ').count(); | ||
26 | if newlines + spaces == len && newlines <= N_NEWLINES && spaces <= N_SPACES { | ||
27 | let mut buf = [0; INLINE_CAP]; | ||
28 | buf[0] = newlines as u8; | ||
29 | buf[1] = spaces as u8; | ||
30 | return SmolStr::Inline { len: WS_TAG, buf }; | ||
31 | } | ||
32 | |||
33 | SmolStr::Heap( | ||
34 | text.to_string().into_boxed_str().into() | ||
35 | ) | ||
36 | } | ||
37 | |||
38 | pub fn as_str(&self) -> &str { | ||
39 | match self { | ||
40 | SmolStr::Heap(data) => &*data, | ||
41 | SmolStr::Inline { len, buf } => { | ||
42 | if *len == WS_TAG { | ||
43 | let newlines = buf[0] as usize; | ||
44 | let spaces = buf[1] as usize; | ||
45 | assert!(newlines <= N_NEWLINES && spaces <= N_SPACES); | ||
46 | return &WS[N_NEWLINES - newlines..N_NEWLINES + spaces] | ||
47 | } | ||
48 | |||
49 | let len = *len as usize; | ||
50 | let buf = &buf[..len]; | ||
51 | unsafe { ::std::str::from_utf8_unchecked(buf) } | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 | |||
57 | const N_NEWLINES: usize = 32; | ||
58 | const N_SPACES: usize = 128; | ||
59 | const WS: &str = | ||
60 | "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n "; | ||
61 | |||
62 | |||
63 | #[cfg(test)] | ||
64 | mod tests { | ||
65 | use super::*; | ||
66 | |||
67 | #[test] | ||
68 | #[cfg(target_pointer_width = "64")] | ||
69 | fn smol_str_is_smol() { | ||
70 | assert_eq!(::std::mem::size_of::<SmolStr>(), 8 + 8 + 8) | ||
71 | } | ||
72 | |||
73 | #[test] | ||
74 | fn test_round_trip() { | ||
75 | let mut text = String::new(); | ||
76 | for n in 0..256 { | ||
77 | let smol = SmolStr::new(&text); | ||
78 | assert_eq!(smol.as_str(), text.as_str()); | ||
79 | text.push_str(&n.to_string()); | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | |||
diff --git a/crates/libsyntax2/src/yellow/green.rs b/crates/libsyntax2/src/yellow/green.rs index f505b26d7..700f2704f 100644 --- a/crates/libsyntax2/src/yellow/green.rs +++ b/crates/libsyntax2/src/yellow/green.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | use { | 2 | |
3 | SyntaxKind, TextUnit, | 3 | use smol_str::SmolStr; |
4 | smol_str::SmolStr, | 4 | |
5 | }; | 5 | use {SyntaxKind, TextUnit}; |
6 | 6 | ||
7 | #[derive(Clone, Debug)] | 7 | #[derive(Clone, Debug)] |
8 | pub(crate) enum GreenNode { | 8 | pub(crate) enum GreenNode { |
@@ -31,7 +31,7 @@ impl GreenNode { | |||
31 | 31 | ||
32 | pub fn text_len(&self) -> TextUnit { | 32 | pub fn text_len(&self) -> TextUnit { |
33 | match self { | 33 | match self { |
34 | GreenNode::Leaf { text, ..} => TextUnit::of_str(text.as_str()), | 34 | GreenNode::Leaf { text, .. } => TextUnit::of_str(text.as_str()), |
35 | GreenNode::Branch(b) => b.text_len(), | 35 | GreenNode::Branch(b) => b.text_len(), |
36 | } | 36 | } |
37 | } | 37 | } |
@@ -54,6 +54,13 @@ impl GreenNode { | |||
54 | } | 54 | } |
55 | } | 55 | } |
56 | } | 56 | } |
57 | |||
58 | pub fn leaf_text(&self) -> Option<SmolStr> { | ||
59 | match self { | ||
60 | GreenNode::Leaf { text, .. } => Some(text.clone()), | ||
61 | GreenNode::Branch(_) => None, | ||
62 | } | ||
63 | } | ||
57 | } | 64 | } |
58 | 65 | ||
59 | #[derive(Clone, Debug)] | 66 | #[derive(Clone, Debug)] |
diff --git a/crates/libsyntax2/src/yellow/syntax.rs b/crates/libsyntax2/src/yellow/syntax.rs index 00f76e51c..b264e008a 100644 --- a/crates/libsyntax2/src/yellow/syntax.rs +++ b/crates/libsyntax2/src/yellow/syntax.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | use std::{fmt, sync::Arc}; | 1 | use std::{fmt, sync::Arc}; |
2 | 2 | ||
3 | use smol_str::SmolStr; | ||
4 | |||
3 | use { | 5 | use { |
4 | yellow::{RedNode, TreeRoot, SyntaxRoot, RedPtr}, | 6 | yellow::{RedNode, TreeRoot, SyntaxRoot, RedPtr}, |
5 | SyntaxKind::{self, *}, | 7 | SyntaxKind::{self, *}, |
@@ -116,6 +118,10 @@ impl<R: TreeRoot> SyntaxNode<R> { | |||
116 | self.first_child().is_none() | 118 | self.first_child().is_none() |
117 | } | 119 | } |
118 | 120 | ||
121 | pub fn leaf_text(&self) -> Option<SmolStr> { | ||
122 | self.red().green().leaf_text() | ||
123 | } | ||
124 | |||
119 | fn red(&self) -> &RedNode { | 125 | fn red(&self) -> &RedNode { |
120 | unsafe { self.red.get(&self.root) } | 126 | unsafe { self.red.get(&self.root) } |
121 | } | 127 | } |