Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/hir_expand/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> {
};
let loc = db.lookup_intern_macro(id);
let arg = loc.kind.arg(db)?;
Some(arg.green())
Some(arg.green().into())
}

fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<TokenExpander>> {
Expand Down
2 changes: 1 addition & 1 deletion crates/syntax/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ doctest = false
[dependencies]
cov-mark = { version = "1.1", features = ["thread-local"] }
itertools = "0.10.0"
rowan = "=0.13.0-pre.3"
rowan = "=0.13.0-pre.5"
rustc_lexer = { version = "716.0.0", package = "rustc-ap-rustc_lexer" }
rustc-hash = "1.1.0"
arrayvec = "0.7"
Expand Down
2 changes: 1 addition & 1 deletion crates/syntax/src/algo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ impl SyntaxRewriter<'_> {

fn element_to_green(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> {
match element {
NodeOrToken::Node(it) => NodeOrToken::Node(it.green()),
NodeOrToken::Node(it) => NodeOrToken::Node(it.green().into_owned()),
NodeOrToken::Token(it) => NodeOrToken::Token(it.green().to_owned()),
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/syntax/src/ast/make.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
}

fn unroot(n: SyntaxNode) -> SyntaxNode {
SyntaxNode::new_root(n.green())
SyntaxNode::new_root(n.green().into())
}

pub mod tokens {
Expand Down
25 changes: 15 additions & 10 deletions crates/syntax/src/ast/node_ext.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
//! Various extension methods to ast Nodes, which are hard to code-generate.
//! Extensions for various expressions live in a sibling `expr_extensions` module.

use std::{fmt, iter::successors};
use std::{borrow::Cow, fmt, iter::successors};

use itertools::Itertools;
use parser::SyntaxKind;
use rowan::{GreenNodeData, GreenTokenData};

use crate::{
ast::{self, support, AstNode, AstToken, AttrsOwner, NameOwner, SyntaxNode},
SmolStr, SyntaxElement, SyntaxToken, TokenText, T,
NodeOrToken, SmolStr, SyntaxElement, SyntaxToken, TokenText, T,
};

impl ast::Lifetime {
pub fn text(&self) -> TokenText {
pub fn text(&self) -> TokenText<'_> {
text_of_first_token(self.syntax())
}
}

impl ast::Name {
pub fn text(&self) -> TokenText {
pub fn text(&self) -> TokenText<'_> {
text_of_first_token(self.syntax())
}
}

impl ast::NameRef {
pub fn text(&self) -> TokenText {
pub fn text(&self) -> TokenText<'_> {
text_of_first_token(self.syntax())
}

Expand All @@ -33,11 +34,15 @@ impl ast::NameRef {
}
}

fn text_of_first_token(node: &SyntaxNode) -> TokenText {
let first_token =
node.green().children().next().and_then(|it| it.into_token()).unwrap().to_owned();
fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> {
fn first_token(green_ref: &GreenNodeData) -> &GreenTokenData {
green_ref.children().next().and_then(NodeOrToken::into_token).unwrap()
}

TokenText(first_token)
match node.green() {
Cow::Borrowed(green_ref) => TokenText::borrowed(first_token(green_ref).text()),
Cow::Owned(green) => TokenText::owned(first_token(&green).to_owned()),
}
}

#[derive(Debug, PartialEq, Eq, Clone)]
Expand Down Expand Up @@ -412,7 +417,7 @@ impl fmt::Display for NameOrNameRef {
}

impl NameOrNameRef {
pub fn text(&self) -> TokenText {
pub fn text(&self) -> TokenText<'_> {
match self {
NameOrNameRef::Name(name) => name.text(),
NameOrNameRef::NameRef(name_ref) => name_ref.text(),
Expand Down
50 changes: 34 additions & 16 deletions crates/syntax/src/token_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,93 @@

use std::{cmp::Ordering, fmt, ops};

pub struct TokenText(pub(crate) rowan::GreenToken);
use rowan::GreenToken;

pub struct TokenText<'a>(pub(crate) Repr<'a>);

pub(crate) enum Repr<'a> {
Borrowed(&'a str),
Owned(GreenToken),
}

impl<'a> TokenText<'a> {
pub(crate) fn borrowed(text: &'a str) -> Self {
TokenText(Repr::Borrowed(text))
}

pub(crate) fn owned(green: GreenToken) -> Self {
TokenText(Repr::Owned(green))
}

impl TokenText {
pub fn as_str(&self) -> &str {
self.0.text()
match self.0 {
Repr::Borrowed(it) => it,
Repr::Owned(ref green) => green.text(),
}
}
}

impl ops::Deref for TokenText {
impl ops::Deref for TokenText<'_> {
type Target = str;

fn deref(&self) -> &str {
self.as_str()
}
}
impl AsRef<str> for TokenText {
impl AsRef<str> for TokenText<'_> {
fn as_ref(&self) -> &str {
self.as_str()
}
}

impl From<TokenText> for String {
impl From<TokenText<'_>> for String {
fn from(token_text: TokenText) -> Self {
token_text.as_str().into()
}
}

impl PartialEq<&'_ str> for TokenText {
impl PartialEq<&'_ str> for TokenText<'_> {
fn eq(&self, other: &&str) -> bool {
self.as_str() == *other
}
}
impl PartialEq<TokenText> for &'_ str {
impl PartialEq<TokenText<'_>> for &'_ str {
fn eq(&self, other: &TokenText) -> bool {
other == self
}
}
impl PartialEq<String> for TokenText {
impl PartialEq<String> for TokenText<'_> {
fn eq(&self, other: &String) -> bool {
self.as_str() == other.as_str()
}
}
impl PartialEq<TokenText> for String {
impl PartialEq<TokenText<'_>> for String {
fn eq(&self, other: &TokenText) -> bool {
other == self
}
}
impl PartialEq for TokenText {
impl PartialEq for TokenText<'_> {
fn eq(&self, other: &TokenText) -> bool {
self.as_str() == other.as_str()
}
}
impl Eq for TokenText {}
impl Ord for TokenText {
impl Eq for TokenText<'_> {}
impl Ord for TokenText<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.as_str().cmp(other.as_str())
}
}
impl PartialOrd for TokenText {
impl PartialOrd for TokenText<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl fmt::Display for TokenText {
impl fmt::Display for TokenText<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_str(), f)
}
}
impl fmt::Debug for TokenText {
impl fmt::Debug for TokenText<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_str(), f)
}
Expand Down