Program instead of Module (#499)

This pr adds an option to parse file as script, not module.


Related: https://github.com/swc-project/swc/issues/491
This commit is contained in:
kdy1 2019-12-11 06:07:21 +00:00
parent 1a48efa4e4
commit fa98c470d6
7 changed files with 65 additions and 17 deletions

View File

@ -27,7 +27,7 @@ pub use self::{
JSXOpeningFragment, JSXSpreadChild, JSXText,
},
lit::{Bool, Lit, Null, Number, Regex, RegexFlags, Str},
module::{Module, ModuleItem, Script},
module::{Module, ModuleItem, Program, Script},
module_decl::{
DefaultDecl, DefaultExportSpecifier, ExportAll, ExportDecl, ExportDefaultDecl,
ExportDefaultExpr, ExportSpecifier, ImportDecl, ImportDefault, ImportSpecific,

View File

@ -2,6 +2,14 @@ use crate::{module_decl::ModuleDecl, stmt::Stmt};
use swc_atoms::JsWord;
use swc_common::{ast_node, Span};
#[ast_node]
pub enum Program {
#[tag("Module")]
Module(Module),
#[tag("Script")]
Script(Script),
}
#[ast_node("Module")]
pub struct Module {
pub span: Span,

View File

@ -77,6 +77,14 @@ impl<'a> Emitter<'a> {
Ok(())
}
#[emitter]
pub fn emit_program(&mut self, node: &Program) -> Result {
match *node {
Program::Module(ref m) => emit!(m),
Program::Script(ref s) => emit!(s),
}
}
#[emitter]
pub fn emit_module(&mut self, node: &Module) -> Result {
if let Some(ref shebang) = node.shebang {

View File

@ -2,7 +2,7 @@ use crate::config::{GlobalPassOption, JscTarget, ModuleConfig};
use atoms::JsWord;
use common::{errors::Handler, SourceMap};
use ecmascript::{
ast::Module,
ast::Program,
parser::Syntax,
transforms::{
chain_at, compat, const_modules, fixer, helpers, hygiene, modules,
@ -33,8 +33,8 @@ impl<'a, 'b, P: Pass> PassBuilder<'a, 'b, P> {
}
}
pub fn then<N>(self, next: N) -> PassBuilder<'a, 'b, JoinedPass<P, N, Module>> {
let pass = chain_at!(Module, self.pass, next);
pub fn then<N>(self, next: N) -> PassBuilder<'a, 'b, JoinedPass<P, N, Program>> {
let pass = chain_at!(Program, self.pass, next);
PassBuilder {
cm: self.cm,
handler: self.handler,
@ -86,7 +86,7 @@ impl<'a, 'b, P: Pass> PassBuilder<'a, 'b, P> {
};
chain_at!(
Module,
Program,
self.pass,
// compat
Optional::new(compat::es2018(), self.target <= JscTarget::Es2018),

View File

@ -4,7 +4,7 @@ use chashmap::CHashMap;
use common::{errors::Handler, FileName, SourceMap};
pub use ecmascript::parser::JscTarget;
use ecmascript::{
ast::{Expr, Module, ModuleItem, Stmt},
ast::{Expr, ModuleItem, Program, Stmt},
parser::{Parser, Session as ParseSess, SourceFileInput, Syntax},
transforms::{
chain_at, const_modules, modules,
@ -81,6 +81,13 @@ pub struct Options {
#[serde(default)]
pub source_root: Option<String>,
#[serde(default = "default_is_module")]
pub is_module: bool,
}
fn default_is_module() -> bool {
true
}
#[derive(Clone, Serialize, Deserialize)]
@ -114,6 +121,7 @@ impl Options {
&self,
cm: &Arc<SourceMap>,
handler: &Handler,
is_module: bool,
config: Option<Config>,
) -> BuiltConfig<impl Pass> {
let mut config = config.unwrap_or_else(Default::default);
@ -163,7 +171,7 @@ impl Options {
};
let pass = chain_at!(
Module,
Program,
// handle jsx
Optional::new(react::react(cm.clone(), transform.react), syntax.jsx()),
Optional::new(typescript::strip(), syntax.typescript()),
@ -191,6 +199,7 @@ impl Options {
pass,
external_helpers,
syntax,
is_module,
source_maps: self
.source_maps
.as_ref()
@ -397,6 +406,7 @@ pub struct BuiltConfig<P: Pass> {
pub minify: bool,
pub external_helpers: bool,
pub source_maps: bool,
pub is_module: bool,
}
#[derive(Default, Clone, Serialize, Deserialize)]

View File

@ -19,7 +19,7 @@ use common::{
GLOBALS,
};
use ecmascript::{
ast::Module,
ast::Program,
codegen::{self, Emitter},
parser::{Parser, Session as ParseSess, Syntax},
transforms::{
@ -69,25 +69,39 @@ impl Compiler {
&self,
fm: Arc<SourceFile>,
syntax: Syntax,
is_module: bool,
comments: Option<&Comments>,
) -> Result<Module, Error> {
) -> Result<Program, Error> {
self.run(|| {
let session = ParseSess {
handler: &self.handler,
};
let mut parser = Parser::new(session, syntax, SourceFileInput::from(&*fm), comments);
let module = parser.parse_module().map_err(|mut e| {
e.emit();
Error::FailedToParseModule {}
})?;
let program = if is_module {
parser
.parse_module()
.map_err(|mut e| {
e.emit();
Error::FailedToParseModule {}
})
.map(Program::Module)?
} else {
parser
.parse_script()
.map_err(|mut e| {
e.emit();
Error::FailedToParseModule {}
})
.map(Program::Script)?
};
Ok(module)
Ok(program)
})
}
pub fn print(
&self,
module: &Module,
program: &Program,
fm: Arc<SourceFile>,
comments: &Comments,
source_map: bool,
@ -127,7 +141,7 @@ impl Compiler {
};
emitter
.emit_module(&module)
.emit_program(&program)
.map_err(|err| Error::FailedToEmitModule { err })?;
}
// Invalid utf8 is valid in javascript world.
@ -173,6 +187,7 @@ impl Compiler {
root_mode,
swcrc,
config_file,
is_module,
..
} = opts;
let root = root
@ -206,7 +221,8 @@ impl Compiler {
if let Some(config_file) = config_file {
config.merge(&config_file.into_config(Some(path))?)
}
let built = opts.build(&self.cm, &self.handler, Some(config));
let built =
opts.build(&self.cm, &self.handler, *is_module, Some(config));
return Ok(built);
}
@ -221,6 +237,7 @@ impl Compiler {
let built = opts.build(
&self.cm,
&self.handler,
*is_module,
Some(config_file.into_config(Some(path))?),
);
return Ok(built);
@ -232,6 +249,7 @@ impl Compiler {
let built = opts.build(
&self.cm,
&self.handler,
*is_module,
match config_file {
Some(config_file) => Some(config_file.into_config(None)?),
None => None,
@ -267,6 +285,7 @@ impl Compiler {
let module = self.parse_js(
fm.clone(),
config.syntax,
config.is_module,
if config.minify { None } else { Some(&comments) },
)?;
let mut pass = config.pass;

View File

@ -12,6 +12,7 @@ fn file(f: &str) -> Result<NormalizedOutput, StdErr> {
fm,
&Options {
swcrc: true,
is_module: true,
..Default::default()
},
);
@ -46,6 +47,8 @@ fn project(dir: &str) {
fm,
&Options {
swcrc: true,
is_module: true,
..Default::default()
},
);