mod parser;
#[macro_use]
mod token_set;
mod event;
mod lossless_tree_sink;
mod lossy_tree_sink;
mod numbers;
mod parse;
mod state;
mod syntax_node;
mod token_source;
#[cfg(test)]
mod tests;
#[macro_use]
pub mod ast;
pub mod syntax;
pub mod util;
pub use crate::{
ast::{AstNode, AstToken},
event::{process, Event},
lossless_tree_sink::LosslessTreeSink,
lossy_tree_sink::LossyTreeSink,
numbers::{parse_js_num, BigInt, JsNum},
parse::*,
parser::{Checkpoint, CompletedMarker, Marker, Parser},
state::{ParserState, StrictMode},
syntax_node::*,
token_set::TokenSet,
token_source::TokenSource,
util::{SyntaxNodeExt, SyntaxTokenExt},
};
pub use rslint_rowan::{SmolStr, SyntaxText, TextRange, TextSize, WalkEvent};
pub use rslint_syntax::*;
pub type ParserError = rslint_errors::Diagnostic;
use std::ops::Range;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct Token {
pub kind: SyntaxKind,
pub range: Range<usize>,
pub len: TextSize,
}
impl From<Token> for Range<usize> {
fn from(token: Token) -> Self {
token.range
}
}
pub trait TreeSink {
fn token(&mut self, kind: SyntaxKind);
fn start_node(&mut self, kind: SyntaxKind);
fn finish_node(&mut self);
fn errors(&mut self, errors: Vec<ParserError>);
fn consume_multiple_tokens(&mut self, amount: u8, kind: SyntaxKind);
}
#[macro_export]
macro_rules! match_ast {
(match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) };
(match ($node:expr) {
$( ast::$ast:ident($it:ident) => $res:expr, )*
_ => $catch_all:expr $(,)?
}) => {{
$( if let Some($it) = ast::$ast::cast($node.clone()) { $res } else )*
{ $catch_all }
}};
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Syntax {
pub file_kind: FileKind,
pub top_level_await: bool,
pub global_return: bool,
pub class_fields: bool,
pub decorators: bool,
}
impl Syntax {
pub fn new(file_kind: FileKind) -> Self {
let mut this = Self {
file_kind,
..Default::default()
};
if file_kind == FileKind::TypeScript {
this = this.typescript();
}
this
}
pub fn top_level_await(mut self) -> Self {
self.top_level_await = true;
self
}
pub fn global_return(mut self) -> Self {
self.global_return = true;
self
}
pub fn class_fields(mut self) -> Self {
self.class_fields = true;
self
}
pub fn decorators(mut self) -> Self {
self.decorators = true;
self
}
pub fn script(mut self) -> Self {
self.file_kind = FileKind::Script;
self
}
pub fn module(mut self) -> Self {
self.file_kind = FileKind::Module;
self
}
pub fn typescript(mut self) -> Self {
self.file_kind = FileKind::TypeScript;
self.class_fields().decorators().top_level_await()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FileKind {
Script,
Module,
TypeScript,
}
impl Default for FileKind {
fn default() -> Self {
FileKind::Script
}
}
impl From<FileKind> for Syntax {
fn from(kind: FileKind) -> Self {
Syntax::new(kind)
}
}