aboutsummaryrefslogtreecommitdiff
path: root/src/yellow/green.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/yellow/green.rs')
-rw-r--r--src/yellow/green.rs67
1 files changed, 18 insertions, 49 deletions
diff --git a/src/yellow/green.rs b/src/yellow/green.rs
index 57579a8f2..2d19c252b 100644
--- a/src/yellow/green.rs
+++ b/src/yellow/green.rs
@@ -1,8 +1,7 @@
1use std::sync::Arc; 1use std::sync::Arc;
2use { 2use {
3 SyntaxKind, TextUnit,
3 smol_str::SmolStr, 4 smol_str::SmolStr,
4 SyntaxKind::{self, *},
5 TextUnit,
6}; 5};
7 6
8#[derive(Clone, Debug)] 7#[derive(Clone, Debug)]
@@ -91,59 +90,23 @@ impl GreenBranch {
91} 90}
92 91
93#[derive(Clone, Debug)] 92#[derive(Clone, Debug)]
94pub(crate) enum GreenLeaf { 93pub(crate) struct GreenLeaf {
95 Whitespace { 94 kind: SyntaxKind,
96 newlines: u8, 95 text: SmolStr,
97 spaces: u8,
98 },
99 Token {
100 kind: SyntaxKind,
101 text: Option<SmolStr>,
102 },
103} 96}
104 97
105impl GreenLeaf { 98impl GreenLeaf {
106 fn new(kind: SyntaxKind, text: &str) -> Self { 99 fn new(kind: SyntaxKind, text: &str) -> Self {
107 if kind == WHITESPACE { 100 let text = SmolStr::new(text);
108 let newlines = text.bytes().take_while(|&b| b == b'\n').count(); 101 GreenLeaf { kind, text }
109 let spaces = text[newlines..].bytes().take_while(|&b| b == b' ').count();
110 if newlines + spaces == text.len() && newlines <= N_NEWLINES && spaces <= N_SPACES {
111 return GreenLeaf::Whitespace {
112 newlines: newlines as u8,
113 spaces: spaces as u8,
114 };
115 }
116 }
117 let text = match SyntaxKind::static_text(kind) {
118 Some(t) => {
119 debug_assert_eq!(t, text);
120 None
121 }
122 None => Some(SmolStr::new(text)),
123 };
124 GreenLeaf::Token { kind, text }
125 } 102 }
126 103
127 pub(crate) fn kind(&self) -> SyntaxKind { 104 pub(crate) fn kind(&self) -> SyntaxKind {
128 match self { 105 self.kind
129 GreenLeaf::Whitespace { .. } => WHITESPACE,
130 GreenLeaf::Token { kind, .. } => *kind,
131 }
132 } 106 }
133 107
134 pub(crate) fn text(&self) -> &str { 108 pub(crate) fn text(&self) -> &str {
135 match self { 109 self.text.as_str()
136 &GreenLeaf::Whitespace { newlines, spaces } => {
137 let newlines = newlines as usize;
138 let spaces = spaces as usize;
139 assert!(newlines <= N_NEWLINES && spaces <= N_SPACES);
140 &WS[N_NEWLINES - newlines..N_NEWLINES + spaces]
141 }
142 GreenLeaf::Token { kind, text } => match text {
143 None => kind.static_text().unwrap(),
144 Some(t) => t.as_str(),
145 },
146 }
147 } 110 }
148 111
149 pub(crate) fn text_len(&self) -> TextUnit { 112 pub(crate) fn text_len(&self) -> TextUnit {
@@ -151,7 +114,13 @@ impl GreenLeaf {
151 } 114 }
152} 115}
153 116
154const N_NEWLINES: usize = 16; 117
155const N_SPACES: usize = 64; 118#[test]
156const WS: &str = 119fn test_sizes() {
157 "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n "; 120 use std::mem::size_of;
121
122 println!("GreenNode = {}", size_of::<GreenNode>());
123 println!("GreenLeaf = {}", size_of::<GreenLeaf>());
124 println!("SyntaxKind = {}", size_of::<SyntaxKind>());
125 println!("SmolStr = {}", size_of::<SmolStr>());
126}