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