EcmaScript/TypeScript parser for the rust programming language.
Features
Heavily tested
Passes almost all tests from tc39/test262.
Error reporting
error: 'implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', or 'yield' cannot be used as an identifier in strict mode
--> invalid.js:3:10
|
3 | function yield() {
| ^^^^^
Error recovery
The parser can recover from some parsing errors. For example, parser returns
Ok(Module) for the code below, while emitting error to handler.
const CONST = 9000 % 2;
const enum D {
// Comma is required, but parser can recover because of the newline.
d = 10
g = CONST
}
Example (lexer)
See lexer.rs in examples directory.
Example (parser)
#[macro_use]
extern crate swc_common;
extern crate swc_ecma_parser;
use swc_common::sync::Lrc;
use swc_common::{
errors::{ColorConfig, Handler},
FileName, FilePathMapping, SourceMap,
};
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax};
fn main() {
let cm: Lrc<SourceMap> = Default::default();
let handler =
Handler::with_tty_emitter(ColorConfig::Auto, true, false,
Some(cm.clone()));
let fm = cm.new_source_file(
FileName::Custom("test.js".into()).into(),
"function foo() {}",
);
let lexer = Lexer::new(
Syntax::Es(Default::default()),
Default::default(),
StringInput::from(&*fm),
None,
);
let mut parser = Parser::new_from(lexer);
for e in parser.take_errors() {
e.into_diagnostic(&handler).emit();
}
let _module = parser
.parse_module()
.map_err(|mut e| {
e.into_diagnostic(&handler).emit()
})
.expect("failed to parser module");
}
Example (flow parser)
# #[cfg(feature = "flow")] {
use swc_common::{sync::Lrc, FileName, SourceMap};
use swc_ecma_ast::EsVersion;
use swc_ecma_parser::{parse_file_as_program, FlowSyntax, Syntax};
let cm: Lrc<SourceMap> = Default::default();
let fm = cm.new_source_file(
FileName::Custom("test.js".into()).into(),
"// @flow\nconst value: number = 1;",
);
let mut recovered_errors = Vec::new();
let program = parse_file_as_program(
&fm,
Syntax::Flow(FlowSyntax {
require_directive: true,
..Default::default()
}),
EsVersion::latest(),
None,
&mut recovered_errors,
)
.expect("flow should parse");
assert!(recovered_errors.is_empty());
let _ = program;
# }
Cargo features
typescript
Enables typescript parser.
flow
Enables flow parser. This feature requires typescript.
verify
Verify more errors, using swc_ecma_visit.
Known issues
Null character after \
Because [String] of rust should only contain valid utf-8 characters while
javascript allows non-utf8 characters, the parser stores invalid utf8
characters in escaped form.
As a result, swc needs a way to distinguish invalid-utf8 code points and
input specified by the user. The parser stores a null character right after
\\ for non-utf8 code points. Note that other parts of swc is aware of this
fact.
Note that this can be changed at anytime with a breaking change.