summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPgBiel <9021226+PgBiel@users.noreply.github.com>2024-06-26 12:58:30 -0300
committerPgBiel <9021226+PgBiel@users.noreply.github.com>2024-06-27 18:06:49 -0300
commitecb0ee51b17fa2a63cc8e691a3d1c2ee2b3f4bf6 (patch)
tree3c92890a620508b839f6c1b3477c5f91e30f0af5
parent05a40ed43d8471ae9c717e5ed2ec7202fcfde179 (diff)
fix newline counting
should probably fix the windows build
-rw-r--r--crates/typst-syntax/src/lexer.rs19
-rw-r--r--crates/typst-syntax/src/node.rs38
2 files changed, 39 insertions, 18 deletions
diff --git a/crates/typst-syntax/src/lexer.rs b/crates/typst-syntax/src/lexer.rs
index b9f28a63..9f08a4bc 100644
--- a/crates/typst-syntax/src/lexer.rs
+++ b/crates/typst-syntax/src/lexer.rs
@@ -1075,6 +1075,25 @@ fn count_newlines(text: &str) -> usize {
newlines
}
+/// Count newlines in text.
+/// Only counts up to 2 newlines.
+pub(crate) fn count_capped_newlines(text: &str) -> u8 {
+ let mut newlines = 0;
+ let mut s = Scanner::new(text);
+ while let Some(c) = s.eat() {
+ if is_newline(c) {
+ if c == '\r' {
+ s.eat_if('\n');
+ }
+ newlines += 1;
+ if newlines == 2 {
+ break;
+ }
+ }
+ }
+ newlines
+}
+
/// Whether a string is a valid Typst identifier.
///
/// In addition to what is specified in the [Unicode Standard][uax31], we allow:
diff --git a/crates/typst-syntax/src/node.rs b/crates/typst-syntax/src/node.rs
index 1f0244cc..6af41eac 100644
--- a/crates/typst-syntax/src/node.rs
+++ b/crates/typst-syntax/src/node.rs
@@ -6,7 +6,7 @@ use std::sync::Arc;
use ecow::{eco_format, eco_vec, EcoString, EcoVec};
use crate::ast::AstNode;
-use crate::{is_newline, FileId, Span, SyntaxKind};
+use crate::{FileId, Span, SyntaxKind};
/// A node in the untyped syntax tree.
#[derive(Clone, Eq, PartialEq, Hash)]
@@ -153,18 +153,15 @@ impl SyntaxNode {
}
}
- /// The amount of newlines in this node or its descendants,
- /// capped at 256, that is, a return value of 256 means that the total
- /// amount of newlines may be 256 or larger.
- pub fn newlines(&self) -> u8 {
+ /// The amount of newlines in this node or its descendants, capped at 2,
+ /// that is, a return value of 2 means that the total amount of newlines
+ /// may be 2 or larger.
+ pub fn capped_newlines(&self) -> u8 {
match &self.0 {
- Repr::Leaf(_) | Repr::Error(_) => self
- .text()
- .chars()
- .filter(|c| is_newline(*c))
- .take(u8::MAX as usize)
- .count() as u8,
- Repr::Inner(inner) => inner.newlines,
+ Repr::Leaf(_) | Repr::Error(_) => {
+ crate::lexer::count_capped_newlines(self.text())
+ }
+ Repr::Inner(inner) => inner.capped_newlines,
}
}
@@ -403,9 +400,9 @@ struct InnerNode {
erroneous: bool,
/// The (capped) amount of newlines in this node's descendants.
/// This is solely used to tell whether this node contains 0, 1, 2 or more
- /// newlines. As such, this number is capped at 256, even though there may
- /// be more newlines inside this node.
- newlines: u8,
+ /// newlines. As such, this number is capped at 2, even though there may be
+ /// more newlines inside this node.
+ capped_newlines: u8,
/// The upper bound of this node's numbering range.
upper: u64,
/// This node's children, losslessly make up this node.
@@ -421,18 +418,23 @@ impl InnerNode {
let mut len = 0;
let mut descendants = 1;
let mut erroneous = false;
+ let mut capped_newlines: u8 = 0;
for child in &children {
len += child.len();
descendants += child.descendants();
erroneous |= child.erroneous();
+
+ if capped_newlines < 2 {
+ capped_newlines = capped_newlines.saturating_add(child.capped_newlines());
+ }
}
Self {
kind,
len,
span: Span::detached(),
- newlines: 0,
+ capped_newlines: capped_newlines.min(2),
descendants,
erroneous,
upper: 0,
@@ -823,7 +825,7 @@ impl<'a> LinkedNode<'a> {
/// node).
pub fn prev_attached_decorator(&self) -> Option<Self> {
let mut cursor = self.prev_sibling_inner()?;
- let mut newlines = cursor.newlines();
+ let mut newlines = cursor.capped_newlines();
let mut at_previous_line = false;
while newlines < 2 {
if cursor.kind() == SyntaxKind::Decorator {
@@ -844,7 +846,7 @@ impl<'a> LinkedNode<'a> {
}
cursor = cursor.prev_sibling_inner()?;
- newlines = cursor.newlines();
+ newlines = cursor.capped_newlines();
}
// Found a parbreak or something else with two or more newlines.