mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 11:59:49 +00:00
Replace ID based TokenMap with proper relative text-ranges / spans
This commit is contained in:
parent
f79439caed
commit
890eb17b4e
80 changed files with 1816 additions and 2046 deletions
|
@ -75,7 +75,7 @@ pub use smol_str::SmolStr;
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Parse<T> {
|
||||
green: GreenNode,
|
||||
errors: Arc<[SyntaxError]>,
|
||||
errors: Option<Arc<[SyntaxError]>>,
|
||||
_ty: PhantomData<fn() -> T>,
|
||||
}
|
||||
|
||||
|
@ -87,14 +87,18 @@ impl<T> Clone for Parse<T> {
|
|||
|
||||
impl<T> Parse<T> {
|
||||
fn new(green: GreenNode, errors: Vec<SyntaxError>) -> Parse<T> {
|
||||
Parse { green, errors: errors.into(), _ty: PhantomData }
|
||||
Parse {
|
||||
green,
|
||||
errors: if errors.is_empty() { None } else { Some(errors.into()) },
|
||||
_ty: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn syntax_node(&self) -> SyntaxNode {
|
||||
SyntaxNode::new_root(self.green.clone())
|
||||
}
|
||||
pub fn errors(&self) -> &[SyntaxError] {
|
||||
&self.errors
|
||||
self.errors.as_deref().unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,10 +112,9 @@ impl<T: AstNode> Parse<T> {
|
|||
}
|
||||
|
||||
pub fn ok(self) -> Result<T, Arc<[SyntaxError]>> {
|
||||
if self.errors.is_empty() {
|
||||
Ok(self.tree())
|
||||
} else {
|
||||
Err(self.errors)
|
||||
match self.errors {
|
||||
Some(e) => Err(e),
|
||||
None => Ok(self.tree()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +132,7 @@ impl Parse<SyntaxNode> {
|
|||
impl Parse<SourceFile> {
|
||||
pub fn debug_dump(&self) -> String {
|
||||
let mut buf = format!("{:#?}", self.tree().syntax());
|
||||
for err in self.errors.iter() {
|
||||
for err in self.errors.as_deref().into_iter().flat_map(<[_]>::iter) {
|
||||
format_to!(buf, "error {:?}: {}\n", err.range(), err);
|
||||
}
|
||||
buf
|
||||
|
@ -141,13 +144,16 @@ impl Parse<SourceFile> {
|
|||
|
||||
fn incremental_reparse(&self, indel: &Indel) -> Option<Parse<SourceFile>> {
|
||||
// FIXME: validation errors are not handled here
|
||||
parsing::incremental_reparse(self.tree().syntax(), indel, self.errors.to_vec()).map(
|
||||
|(green_node, errors, _reparsed_range)| Parse {
|
||||
green: green_node,
|
||||
errors: errors.into(),
|
||||
_ty: PhantomData,
|
||||
},
|
||||
parsing::incremental_reparse(
|
||||
self.tree().syntax(),
|
||||
indel,
|
||||
self.errors.as_deref().unwrap_or_default().iter().cloned(),
|
||||
)
|
||||
.map(|(green_node, errors, _reparsed_range)| Parse {
|
||||
green: green_node,
|
||||
errors: if errors.is_empty() { None } else { Some(errors.into()) },
|
||||
_ty: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
fn full_reparse(&self, indel: &Indel) -> Parse<SourceFile> {
|
||||
|
@ -168,7 +174,11 @@ impl SourceFile {
|
|||
errors.extend(validation::validate(&root));
|
||||
|
||||
assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
|
||||
Parse { green, errors: errors.into(), _ty: PhantomData }
|
||||
Parse {
|
||||
green,
|
||||
errors: if errors.is_empty() { None } else { Some(errors.into()) },
|
||||
_ty: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +285,11 @@ impl ast::TokenTree {
|
|||
|
||||
let (green, errors) = builder.finish_raw();
|
||||
|
||||
Parse { green, errors: errors.into(), _ty: PhantomData }
|
||||
Parse {
|
||||
green,
|
||||
errors: if errors.is_empty() { None } else { Some(errors.into()) },
|
||||
_ty: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
|||
pub(crate) fn incremental_reparse(
|
||||
node: &SyntaxNode,
|
||||
edit: &Indel,
|
||||
errors: Vec<SyntaxError>,
|
||||
errors: impl IntoIterator<Item = SyntaxError>,
|
||||
) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> {
|
||||
if let Some((green, new_errors, old_range)) = reparse_token(node, edit) {
|
||||
return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range));
|
||||
|
@ -147,7 +147,7 @@ fn is_balanced(lexed: &parser::LexedStr<'_>) -> bool {
|
|||
}
|
||||
|
||||
fn merge_errors(
|
||||
old_errors: Vec<SyntaxError>,
|
||||
old_errors: impl IntoIterator<Item = SyntaxError>,
|
||||
new_errors: Vec<SyntaxError>,
|
||||
range_before_reparse: TextRange,
|
||||
edit: &Indel,
|
||||
|
@ -191,8 +191,12 @@ mod tests {
|
|||
let fully_reparsed = SourceFile::parse(&after);
|
||||
let incrementally_reparsed: Parse<SourceFile> = {
|
||||
let before = SourceFile::parse(&before);
|
||||
let (green, new_errors, range) =
|
||||
incremental_reparse(before.tree().syntax(), &edit, before.errors.to_vec()).unwrap();
|
||||
let (green, new_errors, range) = incremental_reparse(
|
||||
before.tree().syntax(),
|
||||
&edit,
|
||||
before.errors.as_deref().unwrap_or_default().iter().cloned(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length");
|
||||
Parse::new(green, new_errors)
|
||||
};
|
||||
|
|
|
@ -38,7 +38,7 @@ fn benchmark_parser() {
|
|||
let tree = {
|
||||
let _b = bench("parsing");
|
||||
let p = SourceFile::parse(&data);
|
||||
assert!(p.errors.is_empty());
|
||||
assert!(p.errors.is_none());
|
||||
assert_eq!(p.tree().syntax.text_range().len(), 352474.into());
|
||||
p.tree()
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue