Given a JavaScript file like this, how can we get an AST from it?
import Thing from "a-place";export const Something = {some: "object",};
We can use swc to parse the source file into an AST using parse_js.
use std::{path::Path, sync::Arc};use swc::config::JscTarget;use swc_common::{errors::{ColorConfig, Handler},SourceMap,};use swc_ecma_parser::{EsConfig, Syntax};fn main() {let cm = Arc::<SourceMap>::default();let handler = Arc::new(Handler::with_tty_emitter(ColorConfig::Auto,true,false,Some(cm.clone()),));let c = swc::Compiler::new(cm.clone(), handler.clone());let fm = cm.load_file(Path::new("foo.js")).expect("failed to load file");let result = c.parse_js(fm,JscTarget::Es2020,Syntax::Es(EsConfig::default()),true,false,);dbg!(result);}
And the resulting AST looks like this, with all of the positional information included.
[src/main.rs:28] result = Ok(Module(Module {span: Span {lo: BytePos(0,),hi: BytePos(77,),ctxt: #0,},body: [ModuleDecl(Import(ImportDecl {span: Span {lo: BytePos(0,),hi: BytePos(28,),ctxt: #0,},specifiers: [Default(ImportDefaultSpecifier {span: Span {lo: BytePos(7,),hi: BytePos(12,),ctxt: #0,},local: Ident {span: Span {lo: BytePos(7,),hi: BytePos(12,),ctxt: #0,},sym: Atom('Thing' type=inline),optional: false,},},),],src: Str {span: Span {lo: BytePos(18,),hi: BytePos(27,),ctxt: #0,},value: Atom('a-place' type=inline),has_escape: false,kind: Normal {contains_quote: true,},},type_only: false,asserts: None,},),),ModuleDecl(ExportDecl(ExportDecl {span: Span {lo: BytePos(30,),hi: BytePos(77,),ctxt: #0,},decl: Var(VarDecl {span: Span {lo: BytePos(37,),hi: BytePos(77,),ctxt: #0,},kind: "const",declare: false,decls: [VarDeclarator {span: Span {lo: BytePos(43,),hi: BytePos(76,),ctxt: #0,},name: Ident(BindingIdent {id: Ident {span: Span {lo: BytePos(43,),hi: BytePos(52,),ctxt: #0,},sym: Atom('Something' type=dynamic),optional: false,},type_ann: None,},),init: Some(Object(ObjectLit {span: Span {lo: BytePos(55,),hi: BytePos(76,),ctxt: #0,},props: [Prop(KeyValue(KeyValueProp {key: Ident(Ident {span: Span {lo: BytePos(59,),hi: BytePos(63,),ctxt: #0,},sym: Atom('some' type=inline),optional: false,},),value: Lit(Str(Str {span: Span {lo: BytePos(65,),hi: BytePos(73,),ctxt: #0,},value: Atom('object' type=static),has_escape: false,kind: Normal {contains_quote: true,},},),),},),),],},),),definite: false,},],},),},),),],shebang: None,},),)