pub mod ast;
pub mod kind;
pub use kind::SyntaxKind;
use kind::RonLang;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TextRange {
start: usize,
end: usize,
}
impl TextRange {
#[inline]
#[must_use]
pub fn new(start: usize, end: usize) -> Self {
debug_assert!(start <= end, "TextRange start must not exceed end");
Self { start, end }
}
#[inline]
#[must_use]
pub fn start(self) -> usize {
self.start
}
#[inline]
#[must_use]
pub fn end(self) -> usize {
self.end
}
#[inline]
#[must_use]
pub fn len(self) -> usize {
self.end - self.start
}
#[inline]
#[must_use]
pub fn is_empty(self) -> bool {
self.start == self.end
}
#[inline]
#[must_use]
pub fn contains(self, offset: usize) -> bool {
self.start <= offset && offset < self.end
}
}
impl From<rowan::TextRange> for TextRange {
#[inline]
fn from(r: rowan::TextRange) -> Self {
Self {
start: usize::from(r.start()),
end: usize::from(r.end()),
}
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct SyntaxNode(rowan::SyntaxNode<RonLang>);
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct SyntaxToken(rowan::SyntaxToken<RonLang>);
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum SyntaxElement {
Node(SyntaxNode),
Token(SyntaxToken),
}
impl SyntaxNode {
#[inline]
#[allow(dead_code)] pub(crate) fn from_rowan(node: rowan::SyntaxNode<RonLang>) -> Self {
Self(node)
}
#[inline]
pub(crate) fn new_root(green: rowan::GreenNode) -> Self {
Self(rowan::SyntaxNode::new_root(green))
}
#[inline]
#[allow(dead_code)] pub(crate) fn raw(&self) -> &rowan::SyntaxNode<RonLang> {
&self.0
}
#[inline]
#[must_use]
pub fn kind(&self) -> SyntaxKind {
self.0.kind()
}
#[inline]
#[must_use]
pub fn text_range(&self) -> TextRange {
self.0.text_range().into()
}
#[must_use]
pub fn text(&self) -> String {
self.0.text().to_string()
}
#[inline]
#[must_use]
pub fn parent(&self) -> Option<SyntaxNode> {
self.0.parent().map(SyntaxNode)
}
pub fn children(&self) -> impl Iterator<Item = SyntaxNode> {
self.0.children().map(SyntaxNode)
}
pub fn children_with_tokens(&self) -> impl Iterator<Item = SyntaxElement> {
self.0.children_with_tokens().map(SyntaxElement::from_rowan)
}
pub fn descendant_tokens(&self) -> impl Iterator<Item = SyntaxToken> {
self.0.descendants_with_tokens().filter_map(|el| match el {
rowan::NodeOrToken::Token(t) => Some(SyntaxToken(t)),
rowan::NodeOrToken::Node(_) => None,
})
}
#[must_use]
pub fn first_token_of(&self, kind: SyntaxKind) -> Option<SyntaxToken> {
self.0
.children_with_tokens()
.filter_map(|el| el.into_token())
.find(|t| t.kind() == kind)
.map(SyntaxToken)
}
}
impl SyntaxToken {
#[inline]
#[must_use]
pub fn kind(&self) -> SyntaxKind {
self.0.kind()
}
#[inline]
#[must_use]
pub fn text_range(&self) -> TextRange {
self.0.text_range().into()
}
#[inline]
#[must_use]
pub fn text(&self) -> &str {
self.0.text()
}
#[inline]
#[must_use]
pub fn parent(&self) -> Option<SyntaxNode> {
self.0.parent().map(SyntaxNode)
}
#[inline]
#[must_use]
pub fn is_trivia(&self) -> bool {
self.kind().is_trivia()
}
}
impl SyntaxElement {
#[inline]
fn from_rowan(el: rowan::SyntaxElement<RonLang>) -> Self {
match el {
rowan::NodeOrToken::Node(n) => Self::Node(SyntaxNode(n)),
rowan::NodeOrToken::Token(t) => Self::Token(SyntaxToken(t)),
}
}
#[inline]
#[must_use]
pub fn kind(&self) -> SyntaxKind {
match self {
Self::Node(n) => n.kind(),
Self::Token(t) => t.kind(),
}
}
#[inline]
#[must_use]
pub fn text_range(&self) -> TextRange {
match self {
Self::Node(n) => n.text_range(),
Self::Token(t) => t.text_range(),
}
}
#[inline]
#[must_use]
pub fn as_node(&self) -> Option<&SyntaxNode> {
match self {
Self::Node(n) => Some(n),
Self::Token(_) => None,
}
}
#[inline]
#[must_use]
pub fn as_token(&self) -> Option<&SyntaxToken> {
match self {
Self::Token(t) => Some(t),
Self::Node(_) => None,
}
}
}
impl std::fmt::Debug for SyntaxNode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}@{:?}", self.kind(), self.text_range())
}
}
impl std::fmt::Debug for SyntaxToken {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{:?}@{:?} {:?}",
self.kind(),
self.text_range(),
self.text()
)
}
}
impl std::fmt::Debug for SyntaxElement {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Node(n) => std::fmt::Debug::fmt(n, f),
Self::Token(t) => std::fmt::Debug::fmt(t, f),
}
}
}