use crate::swc::ast::EsVersion;
use crate::swc::ast::Module;
use crate::swc::common::comments::SingleThreadedComments;
use crate::swc::common::errors::DiagnosticBuilder;
use crate::swc::common::errors::Emitter;
use crate::swc::common::errors::Handler;
use crate::swc::lexer::Capturing;
use crate::swc::lexer::Lexer;
use crate::swc::lexer::Parser;
use crate::swc::lexer::common::parser::Parser as _;
use crate::swc::parser::Syntax;
use crate::swc::parser::token::TokenAndSpan;
use std::path::Path;
use crate::common::SourceTextInfo;
pub fn get_swc_module(file_path: &Path, file_text: &str) -> (Module, Vec<TokenAndSpan>, SourceTextInfo, SingleThreadedComments) {
let handler = Handler::with_emitter(false, false, Box::new(EmptyEmitter {}));
let source_text_info = SourceTextInfo::from_string(file_text.to_string());
let comments: SingleThreadedComments = Default::default();
return {
let ts_config = crate::swc::parser::TsSyntax {
tsx: should_parse_as_jsx(file_path),
decorators: true,
..Default::default()
};
let lexer = Lexer::new(
Syntax::Typescript(ts_config),
EsVersion::Es2022,
source_text_info.as_string_input(),
Some(&comments),
);
let lexer = Capturing::new(lexer);
let mut parser = Parser::new_from(lexer);
let parse_module_result = parser.parse_module();
let iter = &mut parser.input_mut().iter;
let tokens = Capturing::take(iter);
match parse_module_result {
Err(error) => {
let mut diagnostic = error.into_diagnostic(&handler);
diagnostic.cancel();
Err(diagnostic.message())
}
Ok(module) => Ok((module, tokens, source_text_info, comments)),
}
}
.unwrap();
}
#[cfg(feature = "view")]
pub fn get_swc_script(file_path: &Path, file_text: &str) -> (crate::swc::ast::Script, Vec<TokenAndSpan>, SourceTextInfo, SingleThreadedComments) {
let handler = Handler::with_emitter(false, false, Box::new(EmptyEmitter {}));
let source_text_info = SourceTextInfo::from_string(file_text.to_string());
let comments: SingleThreadedComments = Default::default();
return {
let ts_config = crate::swc::parser::TsSyntax {
tsx: should_parse_as_jsx(file_path),
decorators: true,
..Default::default()
};
let lexer = Lexer::new(
Syntax::Typescript(ts_config),
EsVersion::Es2022,
source_text_info.as_string_input(),
Some(&comments),
);
let lexer = Capturing::new(lexer);
let mut parser = Parser::new_from(lexer);
let parse_script_result = parser.parse_script();
let iter = &mut parser.input_mut().iter;
let tokens = Capturing::take(iter);
match parse_script_result {
Err(error) => {
let mut diagnostic = error.into_diagnostic(&handler);
diagnostic.cancel();
Err(diagnostic.message())
}
Ok(script) => Ok((script, tokens, source_text_info, comments)),
}
}
.unwrap();
}
fn should_parse_as_jsx(file_path: &Path) -> bool {
if let Some(extension) = get_lowercase_extension(file_path) {
return extension == "tsx" || extension == "jsx" || extension == "js" || extension == "mjs";
}
true
}
fn get_lowercase_extension(file_path: &Path) -> Option<String> {
file_path.extension().and_then(|e| e.to_str()).map(|f| f.to_lowercase())
}
pub struct EmptyEmitter {}
impl Emitter for EmptyEmitter {
fn emit(&mut self, _: &mut DiagnosticBuilder<'_>) {
}
fn should_show_explain(&self) -> bool {
false
}
}