mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 11:20:54 +00:00
Use raw pointers
This commit is contained in:
parent
b87291a8a4
commit
4e79073e38
@ -3,10 +3,6 @@ mod red;
|
||||
mod syntax;
|
||||
mod builder;
|
||||
|
||||
use std::{
|
||||
sync::{Arc, Weak},
|
||||
mem
|
||||
};
|
||||
pub(crate) use self::{
|
||||
green::{GreenNode, GreenNodeBuilder},
|
||||
red::RedNode,
|
||||
@ -14,30 +10,3 @@ pub(crate) use self::{
|
||||
builder::GreenBuilder,
|
||||
};
|
||||
pub use self::syntax::SyntaxNode;
|
||||
|
||||
// This could be just `*const T`, but we use `Weak` for additional checks
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Ptr<T>(Weak<T>);
|
||||
|
||||
impl<T> Clone for Ptr<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Ptr(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Ptr<T> {
|
||||
fn clone(self_: &Ptr<T>) -> Ptr<T> {
|
||||
Ptr(Weak::clone(&self_.0))
|
||||
}
|
||||
|
||||
fn new(arc: &Arc<T>) -> Ptr<T> {
|
||||
Ptr(Arc::downgrade(arc))
|
||||
}
|
||||
|
||||
unsafe fn get(&self) -> &T {
|
||||
let t = self.0.upgrade()
|
||||
.expect("caller must guarantee that Ptr is not null");
|
||||
let t: &T = &*t;
|
||||
mem::transmute(t)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::sync::{Arc, RwLock};
|
||||
use {
|
||||
TextUnit,
|
||||
yellow::{Ptr, GreenNode},
|
||||
yellow::GreenNode,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -13,7 +13,7 @@ pub(crate) struct RedNode {
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ParentData {
|
||||
parent: Ptr<RedNode>,
|
||||
parent: *const RedNode,
|
||||
start_offset: TextUnit,
|
||||
index_in_parent: usize,
|
||||
}
|
||||
@ -27,7 +27,7 @@ impl RedNode {
|
||||
|
||||
fn new_child(
|
||||
green: GreenNode,
|
||||
parent: Ptr<RedNode>,
|
||||
parent: *const RedNode,
|
||||
start_offset: TextUnit,
|
||||
index_in_parent: usize,
|
||||
) -> RedNode {
|
||||
@ -62,7 +62,7 @@ impl RedNode {
|
||||
self.green.children().len()
|
||||
}
|
||||
|
||||
pub(crate) fn nth_child(&self, me: Ptr<RedNode>, idx: usize) -> Arc<RedNode> {
|
||||
pub(crate) fn nth_child(&self, idx: usize) -> Arc<RedNode> {
|
||||
match &self.children.read().unwrap()[idx] {
|
||||
Some(child) => return child.clone(),
|
||||
None => (),
|
||||
@ -72,7 +72,7 @@ impl RedNode {
|
||||
let green_children = self.green.children();
|
||||
let start_offset = self.start_offset()
|
||||
+ green_children[..idx].iter().map(|x| x.text_len()).sum::<TextUnit>();
|
||||
let child = RedNode::new_child(green_children[idx].clone(), me, start_offset, idx);
|
||||
let child = RedNode::new_child(green_children[idx].clone(), self, start_offset, idx);
|
||||
children[idx] = Some(Arc::new(child))
|
||||
}
|
||||
children[idx].as_ref().unwrap().clone()
|
||||
|
@ -1,18 +1,20 @@
|
||||
use std::{
|
||||
fmt,
|
||||
sync::Arc,
|
||||
ptr
|
||||
};
|
||||
|
||||
use {
|
||||
TextRange, TextUnit,
|
||||
SyntaxKind::{self, *},
|
||||
yellow::{Ptr, RedNode, GreenNode},
|
||||
yellow::{RedNode, GreenNode},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SyntaxNode {
|
||||
pub(crate) root: SyntaxRoot,
|
||||
red: Ptr<RedNode>,
|
||||
// guaranteed to be alive bc SyntaxRoot holds a strong ref
|
||||
red: ptr::NonNull<RedNode>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -29,10 +31,10 @@ pub(crate) struct SyntaxError {
|
||||
|
||||
impl SyntaxNode {
|
||||
pub(crate) fn new(root: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode {
|
||||
let root = Arc::new(RedNode::new_root(root));
|
||||
let red = Ptr::new(&root);
|
||||
let root = SyntaxRoot { red: root, errors: Arc::new(errors) };
|
||||
SyntaxNode { root, red }
|
||||
let red = Arc::new(RedNode::new_root(root));
|
||||
let red_weak: ptr::NonNull<RedNode> = (&*red).into();
|
||||
let root = SyntaxRoot { red, errors: Arc::new(errors) };
|
||||
SyntaxNode { root, red: red_weak }
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> SyntaxKind {
|
||||
@ -58,15 +60,14 @@ impl SyntaxNode {
|
||||
for i in 0..n_children {
|
||||
res.push(SyntaxNode {
|
||||
root: self.root.clone(),
|
||||
red: Ptr::new(&red.nth_child(Ptr::clone(&self.red), i)),
|
||||
red: (&*red.nth_child(i)).into(),
|
||||
});
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
fn red(&self) -> &RedNode {
|
||||
// Safe b/c root ptr keeps red alive
|
||||
unsafe { self.red.get() }
|
||||
unsafe { self.red.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user