mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 13:18:47 +00:00
smol_str to a crate
This commit is contained in:
parent
18486a02fa
commit
ed2ac17133
11 changed files with 101 additions and 23 deletions
|
@ -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" }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
extern crate libsyntax2;
|
||||
extern crate superslice;
|
||||
extern crate itertools;
|
||||
extern crate smol_str;
|
||||
|
||||
mod extend_selection;
|
||||
mod symbols;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
6
crates/smol_str/Cargo.toml
Normal file
6
crates/smol_str/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "smol_str"
|
||||
version = "0.1.0"
|
||||
authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
|
||||
|
||||
[dependencies]
|
|
@ -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;
|
Loading…
Reference in a new issue