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