smol_str to a crate

This commit is contained in:
Aleksey Kladov 2018-08-13 14:24:22 +03:00
parent 18486a02fa
commit ed2ac17133
11 changed files with 101 additions and 23 deletions

View file

@ -9,4 +9,5 @@ itertools = "0.7.8"
superslice = "0.1.0"
libsyntax2 = { path = "../libsyntax2" }
smol_str = { path = "../smol_str" }
assert_eq_text = { path = "../assert_eq_text" }

View file

@ -1,6 +1,7 @@
extern crate libsyntax2;
extern crate superslice;
extern crate itertools;
extern crate smol_str;
mod extend_selection;
mod symbols;

View file

@ -1,3 +1,4 @@
use smol_str::SmolStr;
use libsyntax2::{
SyntaxKind, SyntaxNodeRef, SyntaxRoot, AstNode,
ast::{self, NameOwner},
@ -11,7 +12,7 @@ use TextRange;
#[derive(Debug)]
pub struct FileSymbol {
pub parent: Option<usize>,
pub name: String,
pub name: SmolStr,
pub name_range: TextRange,
pub node_range: TextRange,
pub kind: SyntaxKind,

View file

@ -10,6 +10,7 @@ text_unit = "0.1.2"
itertools = "0.7.5"
drop_bomb = "0.1.4"
parking_lot = "0.6.0"
smol_str = { path = "../smol_str" }
[dev-dependencies]
assert_eq_text = { path = "../assert_eq_text" }

View file

@ -1,6 +1,9 @@
mod generated;
use std::sync::Arc;
use smol_str::SmolStr;
use {
SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError,
SyntaxKind::*,
@ -64,7 +67,9 @@ impl<R: TreeRoot> Function<R> {
}
impl<R: TreeRoot> Name<R> {
pub fn text(&self) -> String {
self.syntax().text()
pub fn text(&self) -> SmolStr {
let ident = self.syntax().first_child()
.unwrap();
ident.leaf_text().unwrap()
}
}

View file

@ -21,10 +21,11 @@
//#![warn(unreachable_pub)] // rust-lang/rust#47816
extern crate itertools;
extern crate text_unit;
extern crate unicode_xid;
extern crate drop_bomb;
extern crate parking_lot;
extern crate smol_str;
extern crate text_unit;
pub mod algo;
pub mod ast;
@ -35,7 +36,6 @@ mod grammar;
mod parser_impl;
mod syntax_kinds;
mod smol_str;
mod yellow;
/// Utilities for simple uses of the parser.
pub mod utils;

View file

@ -1,8 +1,8 @@
use std::sync::Arc;
use {
SyntaxKind, TextUnit,
smol_str::SmolStr,
};
use smol_str::SmolStr;
use {SyntaxKind, TextUnit};
#[derive(Clone, Debug)]
pub(crate) enum GreenNode {
@ -31,7 +31,7 @@ impl GreenNode {
pub fn text_len(&self) -> TextUnit {
match self {
GreenNode::Leaf { text, ..} => TextUnit::of_str(text.as_str()),
GreenNode::Leaf { text, .. } => TextUnit::of_str(text.as_str()),
GreenNode::Branch(b) => b.text_len(),
}
}
@ -54,6 +54,13 @@ impl GreenNode {
}
}
}
pub fn leaf_text(&self) -> Option<SmolStr> {
match self {
GreenNode::Leaf { text, .. } => Some(text.clone()),
GreenNode::Branch(_) => None,
}
}
}
#[derive(Clone, Debug)]

View file

@ -1,5 +1,7 @@
use std::{fmt, sync::Arc};
use smol_str::SmolStr;
use {
yellow::{RedNode, TreeRoot, SyntaxRoot, RedPtr},
SyntaxKind::{self, *},
@ -116,6 +118,10 @@ impl<R: TreeRoot> SyntaxNode<R> {
self.first_child().is_none()
}
pub fn leaf_text(&self) -> Option<SmolStr> {
self.red().green().leaf_text()
}
fn red(&self) -> &RedNode {
unsafe { self.red.get(&self.root) }
}

View file

@ -50,9 +50,10 @@ pub fn handle_document_symbol(
let mut res: Vec<DocumentSymbol> = Vec::new();
for symbol in libeditor::file_symbols(&file) {
let name = symbol.name.to_string();
let doc_symbol = DocumentSymbol {
name: symbol.name.clone(),
detail: Some(symbol.name),
name: name.clone(),
detail: Some(name),
kind: symbol.kind.conv(),
deprecated: None,
range: symbol.node_range.conv_with(&line_index),

View file

@ -0,0 +1,6 @@
[package]
name = "smol_str"
version = "0.1.0"
authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
[dependencies]

View file

@ -1,10 +1,59 @@
use std::{sync::Arc};
use std::{sync::Arc, ops::Deref};
#[derive(Clone, Debug)]
pub struct SmolStr(Repr);
impl SmolStr {
pub fn new(text: &str) -> SmolStr {
SmolStr(Repr::new(text))
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
pub fn to_string(&self) -> String {
self.as_str().to_string()
}
}
impl Deref for SmolStr {
type Target = str;
fn deref(&self) -> &str {
self.as_str()
}
}
impl PartialEq<str> for SmolStr {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
impl PartialEq<SmolStr> for str {
fn eq(&self, other: &SmolStr) -> bool {
other == self
}
}
impl<'a> PartialEq<&'a str> for SmolStr {
fn eq(&self, other: &&'a str) -> bool {
self == *other
}
}
impl<'a> PartialEq<SmolStr> for &'a str {
fn eq(&self, other: &SmolStr) -> bool {
*self == other
}
}
const INLINE_CAP: usize = 22;
const WS_TAG: u8 = (INLINE_CAP + 1) as u8;
#[derive(Clone, Debug)]
pub(crate) enum SmolStr {
enum Repr {
Heap(Arc<str>),
Inline {
len: u8,
@ -12,13 +61,13 @@ pub(crate) enum SmolStr {
},
}
impl SmolStr {
pub fn new(text: &str) -> SmolStr {
impl Repr {
fn new(text: &str) -> Repr {
let len = text.len();
if len <= INLINE_CAP {
let mut buf = [0; INLINE_CAP];
buf[..len].copy_from_slice(text.as_bytes());
return SmolStr::Inline { len: len as u8, buf };
return Repr::Inline { len: len as u8, buf };
}
let newlines = text.bytes().take_while(|&b| b == b'\n').count();
@ -27,23 +76,23 @@ impl SmolStr {
let mut buf = [0; INLINE_CAP];
buf[0] = newlines as u8;
buf[1] = spaces as u8;
return SmolStr::Inline { len: WS_TAG, buf };
return Repr::Inline { len: WS_TAG, buf };
}
SmolStr::Heap(
Repr::Heap(
text.to_string().into_boxed_str().into()
)
}
pub fn as_str(&self) -> &str {
fn as_str(&self) -> &str {
match self {
SmolStr::Heap(data) => &*data,
SmolStr::Inline { len, buf } => {
Repr::Heap(data) => &*data,
Repr::Inline { len, buf } => {
if *len == WS_TAG {
let newlines = buf[0] as usize;
let spaces = buf[1] as usize;
assert!(newlines <= N_NEWLINES && spaces <= N_SPACES);
return &WS[N_NEWLINES - newlines..N_NEWLINES + spaces]
return &WS[N_NEWLINES - newlines..N_NEWLINES + spaces];
}
let len = *len as usize;