1
Fork 0
mirror of https://github.com/RGBCube/cstree synced 2025-07-27 17:17:45 +00:00

add SyntaxToken::text_eq

This commit is contained in:
Domenic Quirl 2021-09-03 22:25:08 +02:00
parent d635e0df92
commit 15ab18dd15
3 changed files with 57 additions and 0 deletions

View file

@ -69,6 +69,11 @@ impl GreenToken {
pub fn text_len(&self) -> TextSize { pub fn text_len(&self) -> TextSize {
self.data().text_len self.data().text_len
} }
#[inline]
pub(crate) fn text_key(&self) -> Spur {
self.data().text
}
} }
impl fmt::Debug for GreenToken { impl fmt::Debug for GreenToken {

View file

@ -176,6 +176,20 @@ impl<L: Language, D> SyntaxToken<L, D> {
self.green().text(resolver) self.green().text(resolver)
} }
/// Returns `true` if `self` and `other` represent equal source text.
///
/// This method is different from the `PartialEq` and `Eq` implementations in that it compares
/// the text and not the token position.
/// It is more efficient than comparing the result of
/// [`resolve_text`](SyntaxToken::resolve_text) because it compares the tokens' interned string
/// keys.
/// Therefore, it also does not require a [`Resolver`].
/// **Note** that the result of the comparison may be wrong when comparing two tokens from
/// different trees that use different interners.
pub fn text_eq(&self, other: &Self) -> bool {
self.green().text_key() == other.green().text_key()
}
/// Returns the unterlying green tree token of this token. /// Returns the unterlying green tree token of this token.
pub fn green(&self) -> &GreenToken { pub fn green(&self) -> &GreenToken {
self.parent self.parent

View file

@ -18,6 +18,15 @@ fn two_level_tree() -> Element<'static> {
]) ])
} }
fn tree_with_eq_tokens() -> Element<'static> {
use Element::*;
Node(vec![
Node(vec![Token("a"), Token("b")]),
Node(vec![Token("c")]),
Node(vec![Token("a"), Token("b"), Token("c")]),
])
}
#[test] #[test]
fn create() { fn create() {
let tree = two_level_tree(); let tree = two_level_tree();
@ -41,6 +50,35 @@ fn create() {
} }
} }
#[test]
fn token_text_eq() {
let tree = tree_with_eq_tokens();
let (tree, _) = build_tree::<()>(&tree);
assert_eq!(tree.kind(), SyntaxKind(0));
let leaf0_0 = tree.children().next().unwrap().children_with_tokens().next().unwrap();
let leaf0_0 = leaf0_0.into_token().unwrap();
let leaf0_1 = tree.children().next().unwrap().children_with_tokens().nth(1).unwrap();
let leaf0_1 = leaf0_1.into_token().unwrap();
let leaf1_0 = tree.children().nth(1).unwrap().children_with_tokens().next().unwrap();
let leaf1_0 = leaf1_0.into_token().unwrap();
let leaf2_0 = tree.children().nth(2).unwrap().children_with_tokens().next().unwrap();
let leaf2_0 = leaf2_0.into_token().unwrap();
let leaf2_1 = tree.children().nth(2).unwrap().children_with_tokens().nth(1).unwrap();
let leaf2_1 = leaf2_1.into_token().unwrap();
let leaf2_2 = tree.children().nth(2).unwrap().children_with_tokens().nth(2).unwrap();
let leaf2_2 = leaf2_2.into_token().unwrap();
assert!(leaf0_0.text_eq(leaf2_0));
assert!(leaf0_1.text_eq(leaf2_1));
assert!(leaf1_0.text_eq(leaf2_2));
assert!(!leaf0_0.text_eq(leaf0_1));
assert!(!leaf2_1.text_eq(leaf2_2));
assert!(!leaf1_0.text_eq(leaf2_0));
}
#[test] #[test]
fn data() { fn data() {
let tree = two_level_tree(); let tree = two_level_tree();