mirror of
https://github.com/typst/typst
synced 2025-05-20 03:55:29 +08:00
Make stuff more elegant
This commit is contained in:
parent
1e4cab393e
commit
7016ab0d12
@ -2,7 +2,7 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use std::ops::Range;
|
||||
use std::ops::{Not, Range};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -10,9 +10,9 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::diag::TypResult;
|
||||
use crate::loading::{FileHash, Loader};
|
||||
use crate::parse::{is_newline, parse, Scanner};
|
||||
use crate::parse::{is_newline, parse, parse_block, Scanner};
|
||||
use crate::syntax::ast::Markup;
|
||||
use crate::syntax::{self, Category, GreenNode, RedNode};
|
||||
use crate::syntax::{self, Category, GreenNode, NodeKind, RedNode, Span};
|
||||
use crate::util::PathExt;
|
||||
|
||||
#[cfg(feature = "codespan-reporting")]
|
||||
@ -284,29 +284,21 @@ impl SourceFile {
|
||||
.extend(newlines(&self.src[start ..]).map(|idx| start + idx));
|
||||
|
||||
// Update the root node.
|
||||
#[cfg(not(feature = "parse-cache"))]
|
||||
{
|
||||
self.root = parse(&self.src);
|
||||
}
|
||||
|
||||
#[cfg(feature = "parse-cache")]
|
||||
{
|
||||
let insertion_span = replace.into_span(self.id);
|
||||
let insertion_span = Span::new(self.id, replace.start, replace.end);
|
||||
let incremental_target =
|
||||
Rc::make_mut(&mut self.root).incremental_parent(insertion_span);
|
||||
|
||||
match incremental_target {
|
||||
Some((child_idx, parent, offset)) => {
|
||||
let child = &parent.children()[child_idx];
|
||||
Some((child, offset)) => {
|
||||
let src = &self.src[offset .. offset + child.len()];
|
||||
let parse_res = match child.kind() {
|
||||
NodeKind::Markup => Some(parse(src)),
|
||||
_ => parse_block(src),
|
||||
}
|
||||
.and_then(|x| x.data().erroneous().not().then(|| x));
|
||||
.and_then(|x| x.erroneous.not().then(|| x));
|
||||
|
||||
if let Some(parse_res) = parse_res {
|
||||
parent.replace_child(child_idx, parse_res);
|
||||
*child = Rc::try_unwrap(parse_res).unwrap();
|
||||
} else {
|
||||
self.root = parse(&self.src);
|
||||
}
|
||||
@ -316,7 +308,6 @@ impl SourceFile {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Provide highlighting categories for the given range of the source file.
|
||||
pub fn highlight<F>(&self, range: Range<usize>, mut f: F)
|
||||
@ -405,6 +396,7 @@ impl<'a> Files<'a> for SourceStore {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::syntax::Green;
|
||||
|
||||
const TEST: &str = "ä\tcde\nf💛g\r\nhi\rjkl";
|
||||
|
||||
|
@ -98,7 +98,7 @@ pub struct GreenNode {
|
||||
/// This node's children, losslessly make up this node.
|
||||
children: Vec<Green>,
|
||||
/// Whether this node or any of its children are erroneous.
|
||||
erroneous: bool,
|
||||
pub erroneous: bool,
|
||||
}
|
||||
|
||||
impl GreenNode {
|
||||
@ -148,12 +148,9 @@ impl GreenNode {
|
||||
self.data().len()
|
||||
}
|
||||
|
||||
/// Find the parent of the deepest incremental-safe node and the index of
|
||||
/// the found child.
|
||||
pub fn incremental_parent(
|
||||
&mut self,
|
||||
span: Span,
|
||||
) -> Option<(usize, &mut GreenNode, usize)> {
|
||||
/// Find the deepest incremental-safe node and its offset in the source
|
||||
/// code.
|
||||
pub fn incremental_parent(&mut self, span: Span) -> Option<(&mut GreenNode, usize)> {
|
||||
self.incremental_parent_internal(span, 0)
|
||||
}
|
||||
|
||||
@ -161,10 +158,8 @@ impl GreenNode {
|
||||
&mut self,
|
||||
span: Span,
|
||||
mut offset: usize,
|
||||
) -> Option<(usize, &mut GreenNode, usize)> {
|
||||
let x = unsafe { &mut *(self as *mut _) };
|
||||
|
||||
for (i, child) in self.children.iter_mut().enumerate() {
|
||||
) -> Option<(&mut GreenNode, usize)> {
|
||||
for child in self.children.iter_mut() {
|
||||
match child {
|
||||
Green::Token(n) => {
|
||||
if offset < span.start {
|
||||
@ -187,15 +182,15 @@ impl GreenNode {
|
||||
&& span.end > offset
|
||||
{
|
||||
// the node is within the span.
|
||||
if n.kind().is_incremental_safe() {
|
||||
let res =
|
||||
Rc::make_mut(n).incremental_parent_internal(span, offset);
|
||||
let safe = n.kind().is_incremental_safe();
|
||||
let mut_n = Rc::make_mut(n);
|
||||
if safe {
|
||||
let res = mut_n.incremental_parent_internal(span, offset);
|
||||
if res.is_none() {
|
||||
return Some((i, x, offset));
|
||||
return Some((mut_n, offset));
|
||||
}
|
||||
} else {
|
||||
return Rc::make_mut(n)
|
||||
.incremental_parent_internal(span, offset);
|
||||
return mut_n.incremental_parent_internal(span, offset);
|
||||
}
|
||||
} else {
|
||||
// the node is overlapping or after after the span; nodes are
|
||||
@ -208,11 +203,6 @@ impl GreenNode {
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
/// Replace one of the node's children.
|
||||
pub fn replace_child(&mut self, index: usize, child: impl Into<Green>) {
|
||||
self.children[index] = child.into();
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GreenNode> for Green {
|
||||
@ -352,7 +342,7 @@ impl Debug for RedNode {
|
||||
}
|
||||
}
|
||||
|
||||
/// A borrowed wrapper for a green node with span information.
|
||||
/// A borrowed wrapper for a [`GreenNode`] with span information.
|
||||
///
|
||||
/// Borrowed variant of [`RedNode`]. Can be [cast](Self::cast) to an AST node.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
@ -387,6 +377,26 @@ impl<'a> RedRef<'a> {
|
||||
Span::new(self.id, self.offset, self.offset + self.green.len())
|
||||
}
|
||||
|
||||
/// Whether the node or its children contain an error.
|
||||
pub fn erroneous(self) -> bool {
|
||||
self.green.erroneous()
|
||||
}
|
||||
|
||||
/// The node's children.
|
||||
pub fn children(self) -> Children<'a> {
|
||||
let children = match &self.green {
|
||||
Green::Node(node) => node.children(),
|
||||
Green::Token(_) => &[],
|
||||
};
|
||||
|
||||
Children {
|
||||
id: self.id,
|
||||
iter: children.iter(),
|
||||
front: self.offset,
|
||||
back: self.offset + self.len(),
|
||||
}
|
||||
}
|
||||
|
||||
/// The error messages for this node and its descendants.
|
||||
pub fn errors(self) -> Vec<Error> {
|
||||
if !self.green.erroneous() {
|
||||
@ -419,21 +429,6 @@ impl<'a> RedRef<'a> {
|
||||
T::from_red(self)
|
||||
}
|
||||
|
||||
/// The node's children.
|
||||
pub fn children(self) -> Children<'a> {
|
||||
let children = match &self.green {
|
||||
Green::Node(node) => node.children(),
|
||||
Green::Token(_) => &[],
|
||||
};
|
||||
|
||||
Children {
|
||||
id: self.id,
|
||||
iter: children.iter(),
|
||||
front: self.offset,
|
||||
back: self.offset + self.len(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the first child that can cast to some AST type.
|
||||
pub fn cast_first_child<T: TypedNode>(self) -> Option<T> {
|
||||
self.children().find_map(RedRef::cast)
|
||||
|
@ -127,12 +127,12 @@ impl Span {
|
||||
|
||||
/// Create a new span with n characters inserted inside of this span.
|
||||
pub fn inserted(mut self, other: Self, n: usize) -> Self {
|
||||
if !self.contains(other.start) || !self.contains(other.end) {
|
||||
if !self.surrounds(other) {
|
||||
panic!();
|
||||
}
|
||||
|
||||
let len_change = (n as isize - other.len() as isize) as usize;
|
||||
self.end += len_change;
|
||||
let len_change = n as isize - other.len() as isize;
|
||||
self.end += len_change as usize;
|
||||
self
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user