Merge #1560
1560: move debug_dump to fmt::Debug r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
@@ -25,7 +25,7 @@ pub fn ancestors_at_offset(
|
||||
) -> impl Iterator<Item = SyntaxNode> {
|
||||
find_token_at_offset(node, offset)
|
||||
.map(|token| token.parent().ancestors())
|
||||
.kmerge_by(|node1, node2| node1.range().len() < node2.range().len())
|
||||
.kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
|
||||
}
|
||||
|
||||
/// Finds a node of specific Ast type at offset. Note that this is slightly
|
||||
|
||||
@@ -51,10 +51,10 @@ impl CheckReparse {
|
||||
for (a, b) in
|
||||
new_parse.tree().syntax().descendants().zip(full_reparse.tree().syntax().descendants())
|
||||
{
|
||||
if (a.kind(), a.range()) != (b.kind(), b.range()) {
|
||||
eprint!("original:\n{}", parse.tree().syntax().debug_dump());
|
||||
eprint!("reparsed:\n{}", new_parse.tree().syntax().debug_dump());
|
||||
eprint!("full reparse:\n{}", full_reparse.tree().syntax().debug_dump());
|
||||
if (a.kind(), a.text_range()) != (b.kind(), b.text_range()) {
|
||||
eprint!("original:\n{:#?}", parse.tree().syntax());
|
||||
eprint!("reparsed:\n{:#?}", new_parse.tree().syntax());
|
||||
eprint!("full reparse:\n{:#?}", full_reparse.tree().syntax());
|
||||
assert_eq!(
|
||||
format!("{:?}", a),
|
||||
format!("{:?}", b),
|
||||
|
||||
@@ -114,7 +114,7 @@ impl Parse<SyntaxNode> {
|
||||
|
||||
impl Parse<SourceFile> {
|
||||
pub fn debug_dump(&self) -> String {
|
||||
let mut buf = self.tree().syntax().debug_dump();
|
||||
let mut buf = format!("{:#?}", self.tree().syntax());
|
||||
for err in self.errors.iter() {
|
||||
writeln!(buf, "error {:?}: {}", err.location(), err.kind()).unwrap();
|
||||
}
|
||||
@@ -234,7 +234,7 @@ fn api_walkthrough() {
|
||||
assert_eq!(expr_syntax.kind(), SyntaxKind::BIN_EXPR);
|
||||
|
||||
// And text range:
|
||||
assert_eq!(expr_syntax.range(), TextRange::from_to(32.into(), 37.into()));
|
||||
assert_eq!(expr_syntax.text_range(), TextRange::from_to(32.into(), 37.into()));
|
||||
|
||||
// You can get node's text as a `SyntaxText` object, which will traverse the
|
||||
// tree collecting token's text:
|
||||
|
||||
@@ -46,7 +46,8 @@ fn reparse_token<'node>(
|
||||
WHITESPACE | COMMENT | IDENT | STRING | RAW_STRING => {
|
||||
if token.kind() == WHITESPACE || token.kind() == COMMENT {
|
||||
// removing a new line may extends previous token
|
||||
if token.text().to_string()[edit.delete - token.range().start()].contains('\n') {
|
||||
if token.text().to_string()[edit.delete - token.text_range().start()].contains('\n')
|
||||
{
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +63,7 @@ fn reparse_token<'node>(
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(next_char) = root.text().char_at(token.range().end()) {
|
||||
if let Some(next_char) = root.text().char_at(token.text_range().end()) {
|
||||
let tokens_with_next_char = tokenize(&format!("{}{}", text, next_char));
|
||||
if tokens_with_next_char.len() == 1 {
|
||||
return None;
|
||||
@@ -70,7 +71,7 @@ fn reparse_token<'node>(
|
||||
}
|
||||
|
||||
let new_token = GreenToken::new(rowan::SyntaxKind(token.kind().into()), text.into());
|
||||
Some((token.replace_with(new_token), token.range()))
|
||||
Some((token.replace_with(new_token), token.text_range()))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
@@ -90,11 +91,12 @@ fn reparse_block<'node>(
|
||||
let mut tree_sink = TextTreeSink::new(&text, &tokens);
|
||||
reparser.parse(&mut token_source, &mut tree_sink);
|
||||
let (green, new_errors) = tree_sink.finish();
|
||||
Some((node.replace_with(green), new_errors, node.range()))
|
||||
Some((node.replace_with(green), new_errors, node.text_range()))
|
||||
}
|
||||
|
||||
fn get_text_after_edit(element: SyntaxElement, edit: &AtomTextEdit) -> String {
|
||||
let edit = AtomTextEdit::replace(edit.delete - element.range().start(), edit.insert.clone());
|
||||
let edit =
|
||||
AtomTextEdit::replace(edit.delete - element.text_range().start(), edit.insert.clone());
|
||||
let text = match element {
|
||||
SyntaxElement::Token(token) => token.text().to_string(),
|
||||
SyntaxElement::Node(node) => node.text().to_string(),
|
||||
@@ -188,8 +190,8 @@ mod tests {
|
||||
};
|
||||
|
||||
assert_eq_text!(
|
||||
&fully_reparsed.tree().syntax().debug_dump(),
|
||||
&incrementally_reparsed.tree().syntax().debug_dump(),
|
||||
&format!("{:#?}", fully_reparsed.tree().syntax()),
|
||||
&format!("{:#?}", incrementally_reparsed.tree().syntax()),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,15 +12,15 @@ pub struct SyntaxNodePtr {
|
||||
|
||||
impl SyntaxNodePtr {
|
||||
pub fn new(node: &SyntaxNode) -> SyntaxNodePtr {
|
||||
SyntaxNodePtr { range: node.range(), kind: node.kind() }
|
||||
SyntaxNodePtr { range: node.text_range(), kind: node.kind() }
|
||||
}
|
||||
|
||||
pub fn to_node(self, root: &SyntaxNode) -> SyntaxNode {
|
||||
assert!(root.parent().is_none());
|
||||
successors(Some(root.clone()), |node| {
|
||||
node.children().find(|it| self.range.is_subrange(&it.range()))
|
||||
node.children().find(|it| self.range.is_subrange(&it.text_range()))
|
||||
})
|
||||
.find(|it| it.range() == self.range && it.kind() == self.kind)
|
||||
.find(|it| it.text_range() == self.range && it.kind() == self.kind)
|
||||
.unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self))
|
||||
}
|
||||
|
||||
|
||||
@@ -6,11 +6,7 @@
|
||||
//! The *real* implementation is in the (language-agnostic) `rowan` crate, this
|
||||
//! modules just wraps its API.
|
||||
|
||||
use std::{
|
||||
fmt::{self, Write},
|
||||
iter::successors,
|
||||
ops::RangeInclusive,
|
||||
};
|
||||
use std::{fmt, iter::successors, ops::RangeInclusive};
|
||||
|
||||
use ra_parser::ParseError;
|
||||
use rowan::GreenNodeBuilder;
|
||||
@@ -36,8 +32,29 @@ pub enum InsertPosition<T> {
|
||||
pub struct SyntaxNode(pub(crate) rowan::cursor::SyntaxNode);
|
||||
|
||||
impl fmt::Debug for SyntaxNode {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "{:?}@{:?}", self.kind(), self.range())
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if f.alternate() {
|
||||
let mut level = 0;
|
||||
for event in self.preorder_with_tokens() {
|
||||
match event {
|
||||
WalkEvent::Enter(element) => {
|
||||
for _ in 0..level {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
match element {
|
||||
SyntaxElement::Node(node) => writeln!(f, "{:?}", node)?,
|
||||
SyntaxElement::Token(token) => writeln!(f, "{:?}", token)?,
|
||||
}
|
||||
level += 1;
|
||||
}
|
||||
WalkEvent::Leave(_) => level -= 1,
|
||||
}
|
||||
}
|
||||
assert_eq!(level, 0);
|
||||
Ok(())
|
||||
} else {
|
||||
write!(f, "{:?}@{:?}", self.kind(), self.text_range())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +80,7 @@ impl SyntaxNode {
|
||||
self.0.kind().0.into()
|
||||
}
|
||||
|
||||
pub fn range(&self) -> TextRange {
|
||||
pub fn text_range(&self) -> TextRange {
|
||||
self.0.text_range()
|
||||
}
|
||||
|
||||
@@ -173,31 +190,6 @@ impl SyntaxNode {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn debug_dump(&self) -> String {
|
||||
let mut level = 0;
|
||||
let mut buf = String::new();
|
||||
|
||||
for event in self.preorder_with_tokens() {
|
||||
match event {
|
||||
WalkEvent::Enter(element) => {
|
||||
for _ in 0..level {
|
||||
buf.push_str(" ");
|
||||
}
|
||||
match element {
|
||||
SyntaxElement::Node(node) => writeln!(buf, "{:?}", node).unwrap(),
|
||||
SyntaxElement::Token(token) => writeln!(buf, "{:?}", token).unwrap(),
|
||||
}
|
||||
level += 1;
|
||||
}
|
||||
WalkEvent::Leave(_) => level -= 1,
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(level, 0);
|
||||
|
||||
buf
|
||||
}
|
||||
|
||||
pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
|
||||
self.0.replace_with(replacement)
|
||||
}
|
||||
@@ -299,7 +291,7 @@ pub struct SyntaxToken(pub(crate) rowan::cursor::SyntaxToken);
|
||||
|
||||
impl fmt::Debug for SyntaxToken {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
|
||||
write!(fmt, "{:?}@{:?}", self.kind(), self.text_range())?;
|
||||
if self.text().len() < 25 {
|
||||
return write!(fmt, " {:?}", self.text());
|
||||
}
|
||||
@@ -329,7 +321,7 @@ impl SyntaxToken {
|
||||
self.0.text()
|
||||
}
|
||||
|
||||
pub fn range(&self) -> TextRange {
|
||||
pub fn text_range(&self) -> TextRange {
|
||||
self.0.text_range()
|
||||
}
|
||||
|
||||
@@ -461,10 +453,10 @@ impl SyntaxElement {
|
||||
.ancestors()
|
||||
}
|
||||
|
||||
pub fn range(&self) -> TextRange {
|
||||
pub fn text_range(&self) -> TextRange {
|
||||
match self {
|
||||
SyntaxElement::Node(it) => it.range(),
|
||||
SyntaxElement::Token(it) => it.range(),
|
||||
SyntaxElement::Node(it) => it.text_range(),
|
||||
SyntaxElement::Token(it) => it.text_range(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ pub struct SyntaxText {
|
||||
|
||||
impl SyntaxText {
|
||||
pub(crate) fn new(node: SyntaxNode) -> SyntaxText {
|
||||
let range = node.range();
|
||||
let range = node.text_range();
|
||||
SyntaxText { node, range }
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ impl SyntaxText {
|
||||
self.node.descendants_with_tokens().try_fold(init, move |acc, element| {
|
||||
let res = match element {
|
||||
SyntaxElement::Token(token) => {
|
||||
let range = match self.range.intersection(&token.range()) {
|
||||
let range = match self.range.intersection(&token.text_range()) {
|
||||
None => return Ok(acc),
|
||||
Some(it) => it,
|
||||
};
|
||||
let slice = if range == token.range() {
|
||||
let slice = if range == token.text_range() {
|
||||
token.text()
|
||||
} else {
|
||||
let range = range - token.range().start();
|
||||
let range = range - token.text_range().start();
|
||||
&token.text()[range]
|
||||
};
|
||||
f(acc, slice)?
|
||||
|
||||
@@ -33,7 +33,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
|
||||
if let Some(end) = text.rfind('\'') {
|
||||
if let Some(without_quotes) = text.get(2..end) {
|
||||
if let Err((off, err)) = unescape::unescape_byte(without_quotes) {
|
||||
let off = token.range().start() + TextUnit::from_usize(off + 2);
|
||||
let off = token.text_range().start() + TextUnit::from_usize(off + 2);
|
||||
acc.push(SyntaxError::new(err.into(), off))
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
|
||||
if let Some(end) = text.rfind('\'') {
|
||||
if let Some(without_quotes) = text.get(1..end) {
|
||||
if let Err((off, err)) = unescape::unescape_char(without_quotes) {
|
||||
let off = token.range().start() + TextUnit::from_usize(off + 1);
|
||||
let off = token.text_range().start() + TextUnit::from_usize(off + 1);
|
||||
acc.push(SyntaxError::new(err.into(), off))
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
|
||||
unescape::unescape_byte_str(without_quotes, &mut |range, char| {
|
||||
if let Err(err) = char {
|
||||
let off = range.start;
|
||||
let off = token.range().start() + TextUnit::from_usize(off + 2);
|
||||
let off = token.text_range().start() + TextUnit::from_usize(off + 2);
|
||||
acc.push(SyntaxError::new(err.into(), off))
|
||||
}
|
||||
})
|
||||
@@ -68,7 +68,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
|
||||
unescape::unescape_str(without_quotes, &mut |range, char| {
|
||||
if let Err(err) = char {
|
||||
let off = range.start;
|
||||
let off = token.range().start() + TextUnit::from_usize(off + 1);
|
||||
let off = token.text_range().start() + TextUnit::from_usize(off + 1);
|
||||
acc.push(SyntaxError::new(err.into(), off))
|
||||
}
|
||||
})
|
||||
@@ -89,9 +89,9 @@ pub(crate) fn validate_block_structure(root: &SyntaxNode) {
|
||||
assert_eq!(
|
||||
node.parent(),
|
||||
pair.parent(),
|
||||
"\nunpaired curleys:\n{}\n{}\n",
|
||||
"\nunpaired curleys:\n{}\n{:#?}\n",
|
||||
root.text(),
|
||||
root.debug_dump(),
|
||||
root,
|
||||
);
|
||||
assert!(
|
||||
node.next_sibling().is_none() && pair.prev_sibling().is_none(),
|
||||
|
||||
@@ -16,6 +16,7 @@ pub(crate) fn validate_block_node(node: ast::Block, errors: &mut Vec<SyntaxError
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
errors
|
||||
.extend(node.attrs().map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().range())))
|
||||
errors.extend(
|
||||
node.attrs().map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().text_range())),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
pub(crate) fn validate_field_expr_node(node: ast::FieldExpr, errors: &mut Vec<SyntaxError>) {
|
||||
if let Some(FieldKind::Index(idx)) = node.field_access() {
|
||||
if idx.text().chars().any(|c| c < '0' || c > '9') {
|
||||
errors.push(SyntaxError::new(InvalidTupleIndexFormat, idx.range()));
|
||||
errors.push(SyntaxError::new(InvalidTupleIndexFormat, idx.text_range()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user