aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-13 12:24:22 +0100
committerAleksey Kladov <[email protected]>2018-08-13 12:24:22 +0100
commited2ac1713326df6b926062efcc6109a20cdf7c37 (patch)
treec1c75d09e2adbbd54190c5b6ce6efdb7ea251da3 /crates/libsyntax2
parent18486a02fae5966e61f16ea7bc5c33c6c7c69487 (diff)
smol_str to a crate
Diffstat (limited to 'crates/libsyntax2')
-rw-r--r--crates/libsyntax2/Cargo.toml1
-rw-r--r--crates/libsyntax2/src/ast/mod.rs9
-rw-r--r--crates/libsyntax2/src/lib.rs4
-rw-r--r--crates/libsyntax2/src/smol_str.rs83
-rw-r--r--crates/libsyntax2/src/yellow/green.rs17
-rw-r--r--crates/libsyntax2/src/yellow/syntax.rs6
6 files changed, 28 insertions, 92 deletions
diff --git a/crates/libsyntax2/Cargo.toml b/crates/libsyntax2/Cargo.toml
index 4c4040fe5..810952a0f 100644
--- a/crates/libsyntax2/Cargo.toml
+++ b/crates/libsyntax2/Cargo.toml
@@ -10,6 +10,7 @@ text_unit = "0.1.2"
10itertools = "0.7.5" 10itertools = "0.7.5"
11drop_bomb = "0.1.4" 11drop_bomb = "0.1.4"
12parking_lot = "0.6.0" 12parking_lot = "0.6.0"
13smol_str = { path = "../smol_str" }
13 14
14[dev-dependencies] 15[dev-dependencies]
15assert_eq_text = { path = "../assert_eq_text" } 16assert_eq_text = { path = "../assert_eq_text" }
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 @@
1mod generated; 1mod generated;
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4
5use smol_str::SmolStr;
6
4use { 7use {
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
66impl<R: TreeRoot> Name<R> { 69impl<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
23extern crate itertools; 23extern crate itertools;
24extern crate text_unit;
25extern crate unicode_xid; 24extern crate unicode_xid;
26extern crate drop_bomb; 25extern crate drop_bomb;
27extern crate parking_lot; 26extern crate parking_lot;
27extern crate smol_str;
28extern crate text_unit;
28 29
29pub mod algo; 30pub mod algo;
30pub mod ast; 31pub mod ast;
@@ -35,7 +36,6 @@ mod grammar;
35mod parser_impl; 36mod parser_impl;
36 37
37mod syntax_kinds; 38mod syntax_kinds;
38mod smol_str;
39mod yellow; 39mod yellow;
40/// Utilities for simple uses of the parser. 40/// Utilities for simple uses of the parser.
41pub mod utils; 41pub 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 @@
1use std::{sync::Arc};
2
3const INLINE_CAP: usize = 22;
4const WS_TAG: u8 = (INLINE_CAP + 1) as u8;
5
6#[derive(Clone, Debug)]
7pub(crate) enum SmolStr {
8 Heap(Arc<str>),
9 Inline {
10 len: u8,
11 buf: [u8; INLINE_CAP],
12 },
13}
14
15impl 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
57const N_NEWLINES: usize = 32;
58const N_SPACES: usize = 128;
59const 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)]
64mod 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 @@
1use std::sync::Arc; 1use std::sync::Arc;
2use { 2
3 SyntaxKind, TextUnit, 3use smol_str::SmolStr;
4 smol_str::SmolStr, 4
5}; 5use {SyntaxKind, TextUnit};
6 6
7#[derive(Clone, Debug)] 7#[derive(Clone, Debug)]
8pub(crate) enum GreenNode { 8pub(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 @@
1use std::{fmt, sync::Arc}; 1use std::{fmt, sync::Arc};
2 2
3use smol_str::SmolStr;
4
3use { 5use {
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 }