feat(babel/compat): Improve performance of babelify (#1626)

swc_babel_compat:
 - Optimize.

swc:
 - Improve performance of comment storage.
This commit is contained in:
강동윤 2021-05-06 14:56:54 +09:00 committed by GitHub
parent abc24c9256
commit 82ef06afb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
159 changed files with 1198 additions and 747 deletions

View File

@ -2,7 +2,7 @@
[build]
rustflags = [
"--cfg", "procmacro2_semver_exempt",
"-C", "target-feature=+sse2",
"-C", "target-feature=+sse2,+aes",
]
rustdocflags = [
@ -12,6 +12,7 @@ rustdocflags = [
[target.aarch64-apple-darwin]
rustflags = [
"--cfg", "procmacro2_semver_exempt",
"-C", "target-feature=+sse2,+aes"
]
[target.aarch64-unknown-linux-gnu]

View File

@ -39,6 +39,8 @@ jobs:
fmt:
name: fmt
runs-on: ubuntu-latest
env:
RUST_LOG: "0"
steps:
- uses: actions/checkout@v2
@ -99,10 +101,14 @@ jobs:
- enum_kind
- from_variant
- jsdoc
- node
- spack
- string_enum
- swc
- swc_atoms
- swc_babel_ast
- swc_babel_compat
- swc_babel_visit
- swc_bundler
- swc_common
- swc_ecma_ast
@ -132,6 +138,7 @@ jobs:
- swc_visit_macros
- testing
- testing_macros
- wasm
exclude:
- os: windows-2019
crate: spack

View File

@ -17,6 +17,7 @@ version = "0.16.0"
name = "swc"
[dependencies]
ahash = "0.7.2"
anyhow = "1"
base64 = "0.12.0"
dashmap = "4.0.2"
@ -44,6 +45,7 @@ swc_ecma_transforms = {version = "0.46.0", path = "./ecmascript/transforms", fea
]}
swc_ecma_utils = {version = "0.34.1", path = "./ecmascript/utils"}
swc_ecma_visit = {version = "0.29.1", path = "./ecmascript/visit"}
swc_node_base = {path = "./node/base"}
swc_visit = {version = "0.2.3", path = "./visit"}
[dev-dependencies]

View File

@ -12,4 +12,6 @@ version = "0.1.0"
[dependencies]
serde = {version = "1", features = ["derive"]}
serde_json = "1.0.62"
swc_common = {version = "0.10.9", path = "../../common"}
swc_atoms = {path = "../../atoms"}
swc_common = {path = "../../common"}
swc_node_base = {path = "../../node/base"}

View File

@ -1,10 +1,10 @@
use serde::{Deserialize, Serialize};
use swc_common::ast_serde;
use crate::{
class::*, comment::Comment, decl::*, expr::*, flow::*, jsx::*, lit::*, module::*, object::*,
pat::*, stmt::*, typescript::*,
};
use serde::{Deserialize, Serialize};
use swc_atoms::JsWord;
use swc_common::ast_serde;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
@ -371,7 +371,7 @@ pub struct Identifier {
#[serde(flatten)]
pub base: BaseNode,
#[serde(default)]
pub name: String,
pub name: JsWord,
#[serde(default)]
pub decorators: Option<Vec<Decorator>>,
#[serde(default)]
@ -559,7 +559,7 @@ pub struct DirectiveLiteral {
#[serde(flatten)]
pub base: BaseNode,
#[serde(default)]
pub value: String,
pub value: JsWord,
}
#[derive(Debug, Clone, PartialEq)]

View File

@ -1,6 +1,3 @@
use serde::{Deserialize, Serialize};
use swc_common::ast_serde;
use crate::{
class::{ClassBody, ClassImpl},
common::{
@ -22,6 +19,9 @@ use crate::{
TSAsExpression, TSNonNullExpression, TSTypeAssertion, TSTypeParameterInstantiation,
},
};
use serde::{Deserialize, Serialize};
use swc_atoms::JsWord;
use swc_common::ast_serde;
#[derive(Debug, Clone, PartialEq)]
#[ast_serde]
@ -155,7 +155,7 @@ pub struct AssignmentExpression {
#[serde(flatten)]
pub base: BaseNode,
#[serde(default)]
pub operator: String,
pub operator: JsWord,
pub left: Box<LVal>,
pub right: Box<Expression>,
}
@ -258,7 +258,7 @@ pub struct V8IntrinsicIdentifier {
#[serde(flatten)]
pub base: BaseNode,
#[serde(default)]
pub name: String,
pub name: JsWord,
}
#[derive(Debug, Clone, PartialEq)]

View File

@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use swc_atoms::JsWord;
use swc_common::ast_serde;
use crate::{
@ -361,7 +362,7 @@ pub struct TypeParameter {
#[serde(default)]
pub variance: Option<Variance>,
#[serde(default)]
pub name: String,
pub name: JsWord,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@ -564,7 +565,7 @@ pub struct StringLiteralTypeAnnotation {
#[serde(flatten)]
pub base: BaseNode,
#[serde(default)]
pub value: String,
pub value: JsWord,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]

View File

@ -1,3 +1,4 @@
use swc_atoms::JsWord;
use swc_common::ast_serde;
use crate::{
@ -133,7 +134,7 @@ pub struct JSXIdentifier {
#[serde(flatten)]
pub base: BaseNode,
#[serde(default)]
pub name: String,
pub name: JsWord,
}
impl From<Identifier> for JSXIdentifier {
@ -218,7 +219,7 @@ pub struct JSXSpreadAttribute {
pub struct JSXText {
#[serde(flatten)]
pub base: BaseNode,
pub value: String,
pub value: JsWord,
}
#[derive(Debug, Clone, PartialEq)]

View File

@ -1,5 +1,8 @@
#![feature(macro_attributes_in_derive_output)]
/// Explicit extern crate to use global allocator.
extern crate swc_node_base;
mod class;
mod comment;
mod common;

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use swc_common::ast_serde;
use crate::{common::BaseNode, expr::Expression, typescript::TSType};
use serde::{Deserialize, Serialize};
use swc_atoms::JsWord;
use swc_common::ast_serde;
#[derive(Debug, Clone, PartialEq)]
#[ast_serde]
@ -29,7 +29,7 @@ pub enum Literal {
pub struct StringLiteral {
#[serde(flatten)]
pub base: BaseNode,
pub value: String,
pub value: JsWord,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@ -69,9 +69,9 @@ pub struct BooleanLiteral {
pub struct RegExpLiteral {
#[serde(flatten)]
pub base: BaseNode,
pub pattern: String,
pub pattern: JsWord,
#[serde(default)]
pub flags: String,
pub flags: JsWord,
}
/// Deprecated. Use RegExpLiteral instead.
@ -80,17 +80,17 @@ pub struct RegExpLiteral {
pub struct RegexLiteral {
#[serde(flatten)]
pub base: BaseNode,
pub pattern: String,
pub pattern: JsWord,
#[serde(default)]
pub flags: String,
pub flags: JsWord,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TemplateElVal {
#[serde(default)]
pub raw: String,
pub raw: JsWord,
#[serde(default)]
pub cooked: Option<String>,
pub cooked: Option<JsWord>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@ -172,5 +172,5 @@ pub struct DecimalLiteral {
#[serde(flatten)]
pub base: BaseNode,
#[serde(default)]
pub value: String,
pub value: JsWord,
}

View File

@ -1,7 +1,3 @@
use serde::{Deserialize, Serialize};
use serde_json::Value;
use swc_common::ast_serde;
use crate::{
class::ClassDeclaration,
comment::Comment,
@ -12,6 +8,10 @@ use crate::{
stmt::Statement,
typescript::TSDeclareFunction,
};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use swc_atoms::JsWord;
use swc_common::ast_serde;
#[derive(Debug, Clone, PartialEq)]
#[ast_serde]
@ -72,7 +72,7 @@ pub struct InterpreterDirective {
#[serde(flatten)]
pub base: BaseNode,
#[serde(default)]
pub value: String,
pub value: JsWord,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]

View File

@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use swc_atoms::JsWord;
use swc_common::ast_serde;
use crate::{
@ -641,7 +642,7 @@ pub struct TSTypeOperator {
pub base: BaseNode,
pub type_annotation: Box<TSType>,
#[serde(default)]
pub operator: String,
pub operator: JsWord,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@ -913,5 +914,5 @@ pub struct TSTypeParameter {
#[serde(default)]
pub default: Option<Box<TSType>>,
#[serde(default)]
pub name: String,
pub name: JsWord,
}

View File

@ -10,19 +10,23 @@ version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
ahash = "0.7.0"
ahash = {version = "0.7.0", features = ["compile-time-rng"]}
anyhow = "1"
copyless = "0.1.5"
rayon = "1.5.0"
serde = {version = "1", features = ["derive"]}
serde_json = "1.0.62"
swc = {path = "../.."}
swc_atoms = {version = "0.2.5", path = "../../atoms"}
swc_babel_ast = {path = "../babel-ast"}
swc_babel_visit = {path = "../babel-visit"}
swc_babel_ast = {path = "../ast"}
swc_babel_visit = {path = "../visit"}
swc_common = {version = "0.10.9", path = "../../common", features = ["tty-emitter", "sourcemap"]}
swc_ecma_ast = {version = "0.43", path = "../../ecmascript/ast"}
swc_ecma_parser = {version = "0.54.2", path = "../../ecmascript/parser"}
swc_ecma_visit = {version = "0.29.1", path = "../../ecmascript/visit"}
swc_node_base = {path = "../../node/base"}
[dev-dependencies]
pretty_assertions = "0.7.1"
swc_ecma_transforms = {path = "../../ecmascript/transforms/"}
walkdir = "2"

View File

@ -0,0 +1,414 @@
/** @prettier */
import { Observable } from '../../Observable';
import { Subscriber } from '../../Subscriber';
import { TeardownLogic, PartialObserver } from '../../types';
export interface AjaxRequest {
url?: string;
body?: any;
user?: string;
async?: boolean;
method?: string;
headers?: object;
timeout?: number;
password?: string;
hasContent?: boolean;
crossDomain?: boolean;
withCredentials?: boolean;
createXHR?: () => XMLHttpRequest;
progressSubscriber?: PartialObserver<ProgressEvent>;
responseType?: string;
}
function isFormData(body: any): body is FormData {
return typeof FormData !== 'undefined' && body instanceof FormData;
}
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
export class AjaxObservable<T> extends Observable<T> {
private request: AjaxRequest;
constructor(urlOrRequest: string | AjaxRequest) {
super();
const request: AjaxRequest = {
async: true,
createXHR: () => new XMLHttpRequest(),
crossDomain: true,
withCredentials: false,
headers: {},
method: 'GET',
responseType: 'json',
timeout: 0,
};
if (typeof urlOrRequest === 'string') {
request.url = urlOrRequest;
} else {
for (const prop in urlOrRequest) {
if (urlOrRequest.hasOwnProperty(prop)) {
(request as any)[prop] = (urlOrRequest as any)[prop];
}
}
}
this.request = request;
}
/** @deprecated This is an internal implementation detail, do not use. */
_subscribe(subscriber: Subscriber<T>): TeardownLogic {
return new AjaxSubscriber(subscriber, this.request);
}
}
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
export class AjaxSubscriber<T> extends Subscriber<Event> {
// @ts-ignore: Property has no initializer and is not definitely assigned
private xhr: XMLHttpRequest;
private done: boolean = false;
constructor(destination: Subscriber<T>, public request: AjaxRequest) {
super(destination);
const headers = (request.headers = request.headers || {});
// force CORS if requested
if (!request.crossDomain && !this.getHeader(headers, 'X-Requested-With')) {
(headers as any)['X-Requested-With'] = 'XMLHttpRequest';
}
// ensure content type is set
let contentTypeHeader = this.getHeader(headers, 'Content-Type');
if (!contentTypeHeader && typeof request.body !== 'undefined' && !isFormData(request.body)) {
(headers as any)['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
}
// properly serialize body
request.body = this.serializeBody(request.body, this.getHeader(request.headers, 'Content-Type'));
this.send();
}
next(e: Event): void {
this.done = true;
const destination = this.destination as Subscriber<any>;
let result: AjaxResponse;
try {
result = new AjaxResponse(e, this.xhr, this.request);
} catch (err) {
return destination.error(err);
}
destination.next(result);
}
private send(): void {
const {
request,
request: { user, method, url, async, password, headers, body },
} = this;
try {
const xhr = (this.xhr = request.createXHR!());
// set up the events before open XHR
// https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
// You need to add the event listeners before calling open() on the request.
// Otherwise the progress events will not fire.
this.setupEvents(xhr, request);
// open XHR
if (user) {
xhr.open(method!, url!, async!, user, password);
} else {
xhr.open(method!, url!, async!);
}
// timeout, responseType and withCredentials can be set once the XHR is open
if (async) {
xhr.timeout = request.timeout!;
xhr.responseType = request.responseType as any;
}
if ('withCredentials' in xhr) {
xhr.withCredentials = !!request.withCredentials;
}
// set headers
this.setHeaders(xhr, headers!);
// finally send the request
if (body) {
xhr.send(body);
} else {
xhr.send();
}
} catch (err) {
this.error(err);
}
}
private serializeBody(body: any, contentType?: string) {
if (!body || typeof body === 'string') {
return body;
} else if (isFormData(body)) {
return body;
}
if (contentType) {
const splitIndex = contentType.indexOf(';');
if (splitIndex !== -1) {
contentType = contentType.substring(0, splitIndex);
}
}
switch (contentType) {
case 'application/x-www-form-urlencoded':
return Object.keys(body)
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(body[key])}`)
.join('&');
case 'application/json':
return JSON.stringify(body);
default:
return body;
}
}
private setHeaders(xhr: XMLHttpRequest, headers: Object) {
for (let key in headers) {
if (headers.hasOwnProperty(key)) {
xhr.setRequestHeader(key, (headers as any)[key]);
}
}
}
private getHeader(headers: {}, headerName: string): any {
for (let key in headers) {
if (key.toLowerCase() === headerName.toLowerCase()) {
return (headers as any)[key];
}
}
return undefined;
}
private setupEvents(xhr: XMLHttpRequest, request: AjaxRequest) {
const progressSubscriber = request.progressSubscriber;
xhr.ontimeout = (e: ProgressEvent) => {
progressSubscriber?.error?.(e);
let error;
try {
error = new AjaxTimeoutError(xhr, request); // TODO: Make betterer.
} catch (err) {
error = err;
}
this.error(error);
};
if (progressSubscriber) {
xhr.upload.onprogress = (e: ProgressEvent) => {
progressSubscriber.next?.(e);
};
}
xhr.onerror = (e: ProgressEvent) => {
progressSubscriber?.error?.(e);
this.error(new AjaxError('ajax error', xhr, request));
};
xhr.onload = (e: ProgressEvent) => {
// 4xx and 5xx should error (https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
if (xhr.status < 400) {
progressSubscriber?.complete?.();
this.next(e);
this.complete();
} else {
progressSubscriber?.error?.(e);
let error;
try {
error = new AjaxError('ajax error ' + xhr.status, xhr, request);
} catch (err) {
error = err;
}
this.error(error);
}
};
}
unsubscribe() {
const { done, xhr } = this;
if (!done && xhr && xhr.readyState !== 4 && typeof xhr.abort === 'function') {
xhr.abort();
}
super.unsubscribe();
}
}
/**
* A normalized AJAX response.
*
* @see {@link ajax}
*
* @class AjaxResponse
*/
export class AjaxResponse {
/** @type {number} The HTTP status code */
status: number;
/** @type {string|ArrayBuffer|Document|object|any} The response data */
response: any;
/** @type {string} The raw responseText */
// @ts-ignore: Property has no initializer and is not definitely assigned
responseText: string;
/** @type {string} The responseType (e.g. 'json', 'arraybuffer', or 'xml') */
responseType: string;
constructor(public originalEvent: Event, public xhr: XMLHttpRequest, public request: AjaxRequest) {
this.status = xhr.status;
this.responseType = xhr.responseType || request.responseType!;
this.response = getXHRResponse(xhr);
}
}
export type AjaxErrorNames = 'AjaxError' | 'AjaxTimeoutError';
/**
* A normalized AJAX error.
*
* @see {@link ajax}
*
* @class AjaxError
*/
export interface AjaxError extends Error {
/**
* The XHR instance associated with the error
*/
xhr: XMLHttpRequest;
/**
* The AjaxRequest associated with the error
*/
request: AjaxRequest;
/**
*The HTTP status code
*/
status: number;
/**
*The responseType (e.g. 'json', 'arraybuffer', or 'xml')
*/
responseType: XMLHttpRequestResponseType;
/**
* The response data
*/
response: any;
}
export interface AjaxErrorCtor {
/**
* Internal use only. Do not manually create instances of this type.
* @internal
*/
new (message: string, xhr: XMLHttpRequest, request: AjaxRequest): AjaxError;
}
const AjaxErrorImpl = (() => {
function AjaxErrorImpl(this: any, message: string, xhr: XMLHttpRequest, request: AjaxRequest): AjaxError {
Error.call(this);
this.message = message;
this.name = 'AjaxError';
this.xhr = xhr;
this.request = request;
this.status = xhr.status;
this.responseType = xhr.responseType;
let response: any;
try {
response = getXHRResponse(xhr);
} catch (err) {
response = xhr.responseText;
}
this.response = response;
return this;
}
AjaxErrorImpl.prototype = Object.create(Error.prototype);
return AjaxErrorImpl;
})();
/**
* Thrown when an error occurs during an AJAX request.
* This is only exported because it is useful for checking to see if an error
* is an `instanceof AjaxError`. DO NOT create new instances of `AjaxError` with
* the constructor.
*
* @class AjaxError
* @see ajax
*/
export const AjaxError: AjaxErrorCtor = AjaxErrorImpl as any;
function getXHRResponse(xhr: XMLHttpRequest) {
switch (xhr.responseType) {
case 'json': {
if ('response' in xhr) {
return xhr.response;
} else {
// IE
const ieXHR: any = xhr;
return JSON.parse(ieXHR.responseText);
}
}
case 'document':
return xhr.responseXML;
case 'text':
default: {
if ('response' in xhr) {
return xhr.response;
} else {
// IE
const ieXHR: any = xhr;
return ieXHR.responseText;
}
}
}
}
export interface AjaxTimeoutError extends AjaxError {}
export interface AjaxTimeoutErrorCtor {
/**
* Internal use only. Do not manually create instances of this type.
* @internal
*/
new (xhr: XMLHttpRequest, request: AjaxRequest): AjaxTimeoutError;
}
const AjaxTimeoutErrorImpl = (() => {
function AjaxTimeoutErrorImpl(this: any, xhr: XMLHttpRequest, request: AjaxRequest) {
AjaxError.call(this, 'ajax timeout', xhr, request);
this.name = 'AjaxTimeoutError';
return this;
}
AjaxTimeoutErrorImpl.prototype = Object.create(AjaxError.prototype);
return AjaxTimeoutErrorImpl;
})();
/**
* Thrown when an AJAX request timesout. Not to be confused with {@link TimeoutError}.
*
* This is exported only because it is useful for checking to see if errors are an
* `instanceof AjaxTimeoutError`. DO NOT use the constructor to create an instance of
* this type.
*
* @class AjaxTimeoutError
* @see ajax
*/
export const AjaxTimeoutError: AjaxTimeoutErrorCtor = AjaxTimeoutErrorImpl as any;

View File

@ -0,0 +1,140 @@
#![feature(test)]
extern crate test;
use std::{hint::black_box, sync::Arc};
use swc_babel_compat::Babelify;
use swc_babel_compat::Context;
use swc_common::SourceFile;
use swc_common::{
errors::{ColorConfig, Handler},
FileName, FilePathMapping, SourceMap,
};
use swc_ecma_ast::Program;
use swc_ecma_parser::{JscTarget, Syntax};
use swc_ecma_transforms::compat::es2020;
use swc_ecma_transforms::typescript;
use swc_ecma_visit::FoldWith;
use test::Bencher;
static SOURCE: &str = include_str!("assets/AjaxObservable.ts");
fn mk() -> swc::Compiler {
let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));
let handler = Arc::new(Handler::with_tty_emitter(
ColorConfig::Always,
true,
false,
Some(cm.clone()),
));
let c = swc::Compiler::new(cm.clone(), handler);
c
}
fn parse(c: &swc::Compiler, src: &str) -> (Arc<SourceFile>, Program) {
let fm = c.cm.new_source_file(
FileName::Real("rxjs/src/internal/observable/dom/AjaxObservable.ts".into()),
src.to_string(),
);
let module = c
.parse_js(
fm.clone(),
JscTarget::Es5,
Syntax::Typescript(Default::default()),
true,
true,
)
.unwrap();
(fm, module)
}
#[bench]
fn babelify_only(b: &mut Bencher) {
b.bytes = SOURCE.len() as _;
let c = mk();
let (fm, module) = parse(&c, SOURCE);
let module = c.run_transform(false, || {
module
.fold_with(&mut typescript::strip())
.fold_with(&mut es2020())
});
b.iter(|| {
let program = module.clone();
let ctx = Context {
fm: fm.clone(),
cm: c.cm.clone(),
comments: c.comments().clone(),
};
let babel_ast = program.babelify(&ctx);
black_box(babel_ast)
});
}
fn parse_and_babelify(b: &mut Bencher, _name: &str, src: &str) {
b.bytes = src.len() as _;
let c = mk();
b.iter(|| {
let (fm, program) = parse(&c, src);
let ctx = Context {
fm,
cm: c.cm.clone(),
comments: c.comments().clone(),
};
let babel_ast = program.babelify(&ctx);
black_box(babel_ast);
});
}
/// https://esprima.org/test/compare.html
macro_rules! src_to_babel_ast {
($name:ident, $src:expr) => {
#[bench]
fn $name(b: &mut Bencher) {
parse_and_babelify(b, stringify!($name), $src);
}
};
}
src_to_babel_ast!(
parse_and_babelify_angular,
include_str!("../../../ecmascript/parser/benches/files/angular-1.2.5.js")
);
src_to_babel_ast!(
parse_and_babelify_backbone,
include_str!("../../../ecmascript/parser/benches/files/backbone-1.1.0.js")
);
src_to_babel_ast!(
parse_and_babelify_jquery,
include_str!("../../../ecmascript/parser/benches/files/jquery-1.9.1.js")
);
src_to_babel_ast!(
parse_and_babelify_jquery_mobile,
include_str!("../../../ecmascript/parser/benches/files/jquery.mobile-1.4.2.js")
);
src_to_babel_ast!(
parse_and_babelify_mootools,
include_str!("../../../ecmascript/parser/benches/files/mootools-1.4.5.js")
);
src_to_babel_ast!(
parse_and_babelify_underscore,
include_str!("../../../ecmascript/parser/benches/files/underscore-1.5.2.js")
);
src_to_babel_ast!(
parse_and_babelify_yui,
include_str!("../../../ecmascript/parser/benches/files/yui-3.12.0.js")
);

View File

@ -1,4 +1,5 @@
use crate::{extract_class_body_span, Babelify, Context};
use copyless::BoxHelper;
use serde_json::value::Value;
use swc_babel_ast::{
ClassBody, ClassBodyEl, ClassExpression, ClassMethod as BabelClassMethod, ClassMethodKind,
@ -13,26 +14,26 @@ impl Babelify for Class {
type Output = ClassExpression;
fn babelify(self, ctx: &Context) -> Self::Output {
let body = ClassBody {
base: ctx.base(extract_class_body_span(&self, &ctx)),
body: self.body.babelify(ctx),
};
ClassExpression {
base: ctx.base(self.span),
decorators: Some(
self.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
body: extract_class_body(&self, &ctx),
decorators: Some(self.decorators.babelify(ctx)),
body,
super_class: self
.super_class
.map(|expr| Box::new(expr.babelify(ctx).into())),
.map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
type_parameters: self.type_params.map(|param| param.babelify(ctx).into()),
super_type_parameters: self
.super_type_params
.map(|param| param.babelify(ctx).into()),
implements: Some(
self.implements
.iter()
.map(|imp| imp.clone().babelify(ctx).into())
.into_iter()
.map(|imp| imp.babelify(ctx).into())
.collect(),
),
id: Default::default(),
@ -60,17 +61,6 @@ impl Babelify for ClassMember {
}
}
fn extract_class_body(class: &Class, ctx: &Context) -> ClassBody {
ClassBody {
base: ctx.base(extract_class_body_span(&class, &ctx)),
body: class
.body
.iter()
.map(|mem| mem.clone().babelify(ctx))
.collect(),
}
}
impl Babelify for ClassProp {
type Output = ClassProperty;
@ -78,15 +68,14 @@ impl Babelify for ClassProp {
ClassProperty {
base: ctx.base(self.span),
key: self.key.babelify(ctx).into(),
value: self.value.map(|val| Box::new(val.babelify(ctx).into())),
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx).into())),
value: self
.value
.map(|val| Box::alloc().init(val.babelify(ctx).into())),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx).into())),
is_static: Some(self.is_static),
decorators: Some(
self.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
decorators: Some(self.decorators.babelify(ctx)),
computed: Some(self.computed),
accessibility: self.accessibility.map(|access| access.babelify(ctx)),
is_abstract: Some(self.is_abstract),
@ -105,15 +94,14 @@ impl Babelify for PrivateProp {
ClassPrivateProperty {
base: ctx.base(self.span),
key: self.key.babelify(ctx),
value: self.value.map(|expr| Box::new(expr.babelify(ctx).into())),
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx).into())),
value: self
.value
.map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx).into())),
static_any: Value::Bool(self.is_static),
decorators: Some(
self.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
decorators: Some(self.decorators.babelify(ctx)),
}
}
}
@ -131,27 +119,16 @@ impl Babelify for ClassMethod {
accessibility: self.accessibility.map(|access| access.babelify(ctx)),
is_abstract: Some(self.is_abstract),
optional: Some(self.is_optional),
params: self
.function
.params
.iter()
.map(|param| param.clone().babelify(ctx))
.collect(),
params: self.function.params.babelify(ctx),
body: self.function.body.unwrap().babelify(ctx),
generator: Some(self.function.is_generator),
is_async: Some(self.function.is_async),
decorators: Some(
self.function
.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
decorators: Some(self.function.decorators.babelify(ctx)),
type_parameters: self.function.type_params.map(|t| t.babelify(ctx).into()),
return_type: self
.function
.return_type
.map(|t| Box::new(t.babelify(ctx).into())),
.map(|t| Box::alloc().init(t.babelify(ctx).into())),
computed: Default::default(),
}
}
@ -170,27 +147,16 @@ impl Babelify for PrivateMethod {
accessibility: self.accessibility.map(|access| access.babelify(ctx)),
is_abstract: Some(self.is_abstract),
optional: Some(self.is_optional),
params: self
.function
.params
.iter()
.map(|param| param.clone().babelify(ctx))
.collect(),
params: self.function.params.babelify(ctx),
body: self.function.body.unwrap().babelify(ctx),
generator: Some(self.function.is_generator),
is_async: Some(self.function.is_async),
decorators: Some(
self.function
.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
decorators: Some(self.function.decorators.babelify(ctx)),
type_parameters: self.function.type_params.map(|t| t.babelify(ctx).into()),
return_type: self
.function
.return_type
.map(|t| Box::new(t.babelify(ctx).into())),
.map(|t| Box::alloc().init(t.babelify(ctx).into())),
computed: Default::default(),
}
}
@ -204,11 +170,7 @@ impl Babelify for Constructor {
base: ctx.base(self.span),
kind: Some(ClassMethodKind::Constructor),
key: self.key.babelify(ctx).into(),
params: self
.params
.iter()
.map(|param| param.clone().babelify(ctx))
.collect(),
params: self.params.babelify(ctx),
body: self.body.unwrap().babelify(ctx),
access: self.accessibility.map(|access| access.babelify(ctx)),
accessibility: self.accessibility.map(|access| access.babelify(ctx)),
@ -231,7 +193,7 @@ impl Babelify for Decorator {
fn babelify(self, ctx: &Context) -> Self::Output {
BabelDecorator {
base: ctx.base(self.span),
expression: Box::new(self.expr.babelify(ctx).into()),
expression: Box::alloc().init(self.expr.babelify(ctx).into()),
}
}
}

View File

@ -1,4 +1,5 @@
use crate::{extract_class_body_span, Babelify, Context};
use copyless::BoxHelper;
use swc_babel_ast::{
ClassBody, ClassDeclaration, Declaration, FunctionDeclaration, VariableDeclaration,
VariableDeclarationKind, VariableDeclarator,
@ -68,7 +69,7 @@ impl Babelify for ClassDecl {
ClassDeclaration {
base: class.base,
id: self.ident.babelify(ctx),
super_class: class.super_class.map(|s| Box::new(*s)),
super_class: class.super_class.map(|s| Box::alloc().init(*s)),
body: ClassBody {
base: ctx.base(body_span),
..class.body
@ -92,11 +93,7 @@ impl Babelify for VarDecl {
base: ctx.base(self.span),
kind: self.kind.babelify(ctx),
declare: Some(self.declare),
declarations: self
.decls
.iter()
.map(|decl| decl.clone().babelify(ctx))
.collect(),
declarations: self.decls.babelify(ctx),
}
}
}
@ -120,7 +117,7 @@ impl Babelify for VarDeclarator {
VariableDeclarator {
base: ctx.base(self.span),
id: self.name.babelify(ctx).into(),
init: self.init.map(|i| Box::new(i.babelify(ctx).into())),
init: self.init.map(|i| Box::alloc().init(i.babelify(ctx).into())),
definite: Some(self.definite),
}
}

View File

@ -1,4 +1,6 @@
use crate::{Babelify, Context};
use copyless::BoxHelper;
use serde::{Deserialize, Serialize};
use swc_babel_ast::{
ArrayExprEl, ArrayExpression, ArrowFuncExprBody, ArrowFunctionExpression, AssignmentExpression,
AwaitExpression, BinaryExprLeft, BinaryExpression, CallExpression, Callee, ClassExpression,
@ -9,8 +11,6 @@ use swc_babel_ast::{
TaggedTemplateExpression, TemplateElVal, TemplateElement, TemplateLiteral, TemplateLiteralExpr,
ThisExpression, UnaryExpression, UpdateExpression, YieldExpression,
};
use serde::{Deserialize, Serialize};
use swc_common::Spanned;
use swc_ecma_ast::{
ArrayLit, ArrowExpr, AssignExpr, AwaitExpr, BinExpr, BinaryOp, BlockStmtOrExpr, CallExpr,
@ -30,47 +30,63 @@ impl Babelify for Expr {
fn babelify(self, ctx: &Context) -> Self::Output {
match self {
Expr::This(t) => ExprOutput::Expr(Box::new(Expression::This(t.babelify(ctx)))),
Expr::Array(a) => ExprOutput::Expr(Box::new(Expression::Array(a.babelify(ctx)))),
Expr::Object(o) => ExprOutput::Expr(Box::new(Expression::Object(o.babelify(ctx)))),
Expr::Fn(f) => ExprOutput::Expr(Box::new(Expression::Func(f.babelify(ctx)))),
Expr::Unary(u) => ExprOutput::Expr(Box::new(Expression::Unary(u.babelify(ctx)))),
Expr::Update(u) => ExprOutput::Expr(Box::new(Expression::Update(u.babelify(ctx)))),
Expr::This(t) => ExprOutput::Expr(Box::alloc().init(Expression::This(t.babelify(ctx)))),
Expr::Array(a) => {
ExprOutput::Expr(Box::alloc().init(Expression::Array(a.babelify(ctx))))
}
Expr::Object(o) => {
ExprOutput::Expr(Box::alloc().init(Expression::Object(o.babelify(ctx))))
}
Expr::Fn(f) => ExprOutput::Expr(Box::alloc().init(Expression::Func(f.babelify(ctx)))),
Expr::Unary(u) => {
ExprOutput::Expr(Box::alloc().init(Expression::Unary(u.babelify(ctx))))
}
Expr::Update(u) => {
ExprOutput::Expr(Box::alloc().init(Expression::Update(u.babelify(ctx))))
}
Expr::Bin(b) => match b.babelify(ctx) {
BinaryOrLogicalExpr::Binary(bin) => {
ExprOutput::Expr(Box::new(Expression::Binary(bin)))
ExprOutput::Expr(Box::alloc().init(Expression::Binary(bin)))
}
BinaryOrLogicalExpr::Logical(log) => {
ExprOutput::Expr(Box::new(Expression::Logical(log)))
ExprOutput::Expr(Box::alloc().init(Expression::Logical(log)))
}
},
Expr::Assign(a) => ExprOutput::Expr(Box::new(Expression::Assignment(a.babelify(ctx)))),
Expr::Member(m) => ExprOutput::Expr(Box::new(Expression::Member(m.babelify(ctx)))),
Expr::Cond(c) => ExprOutput::Expr(Box::new(Expression::Conditional(c.babelify(ctx)))),
Expr::Call(c) => ExprOutput::Expr(Box::new(Expression::Call(c.babelify(ctx)))),
Expr::New(n) => ExprOutput::Expr(Box::new(Expression::New(n.babelify(ctx)))),
Expr::Seq(s) => ExprOutput::Expr(Box::new(Expression::Sequence(s.babelify(ctx)))),
Expr::Ident(i) => ExprOutput::Expr(Box::new(Expression::Id(i.babelify(ctx)))),
Expr::Assign(a) => {
ExprOutput::Expr(Box::alloc().init(Expression::Assignment(a.babelify(ctx))))
}
Expr::Member(m) => {
ExprOutput::Expr(Box::alloc().init(Expression::Member(m.babelify(ctx))))
}
Expr::Cond(c) => {
ExprOutput::Expr(Box::alloc().init(Expression::Conditional(c.babelify(ctx))))
}
Expr::Call(c) => ExprOutput::Expr(Box::alloc().init(Expression::Call(c.babelify(ctx)))),
Expr::New(n) => ExprOutput::Expr(Box::alloc().init(Expression::New(n.babelify(ctx)))),
Expr::Seq(s) => {
ExprOutput::Expr(Box::alloc().init(Expression::Sequence(s.babelify(ctx))))
}
Expr::Ident(i) => ExprOutput::Expr(Box::alloc().init(Expression::Id(i.babelify(ctx)))),
Expr::Lit(lit) => {
match lit {
Lit::Str(s) => {
ExprOutput::Expr(Box::new(Expression::StringLiteral(s.babelify(ctx))))
}
Lit::Bool(b) => {
ExprOutput::Expr(Box::new(Expression::BooleanLiteral(b.babelify(ctx))))
}
Lit::Null(n) => {
ExprOutput::Expr(Box::new(Expression::NullLiteral(n.babelify(ctx))))
}
Lit::Num(n) => {
ExprOutput::Expr(Box::new(Expression::NumericLiteral(n.babelify(ctx))))
}
Lit::BigInt(i) => {
ExprOutput::Expr(Box::new(Expression::BigIntLiteral(i.babelify(ctx))))
}
Lit::Regex(r) => {
ExprOutput::Expr(Box::new(Expression::RegExpLiteral(r.babelify(ctx))))
}
Lit::Str(s) => ExprOutput::Expr(
Box::alloc().init(Expression::StringLiteral(s.babelify(ctx))),
),
Lit::Bool(b) => ExprOutput::Expr(
Box::alloc().init(Expression::BooleanLiteral(b.babelify(ctx))),
),
Lit::Null(n) => ExprOutput::Expr(
Box::alloc().init(Expression::NullLiteral(n.babelify(ctx))),
),
Lit::Num(n) => ExprOutput::Expr(
Box::alloc().init(Expression::NumericLiteral(n.babelify(ctx))),
),
Lit::BigInt(i) => ExprOutput::Expr(
Box::alloc().init(Expression::BigIntLiteral(i.babelify(ctx))),
),
Lit::Regex(r) => ExprOutput::Expr(
Box::alloc().init(Expression::RegExpLiteral(r.babelify(ctx))),
),
Lit::JSXText(_) => panic!(
"illegal conversion: Cannot convert {:?} to ExprOutput",
&lit
@ -78,32 +94,42 @@ impl Babelify for Expr {
}
}
Expr::Tpl(t) => {
ExprOutput::Expr(Box::new(Expression::TemplateLiteral(t.babelify(ctx))))
ExprOutput::Expr(Box::alloc().init(Expression::TemplateLiteral(t.babelify(ctx))))
}
Expr::TaggedTpl(t) => {
ExprOutput::Expr(Box::new(Expression::TaggedTemplate(t.babelify(ctx))))
ExprOutput::Expr(Box::alloc().init(Expression::TaggedTemplate(t.babelify(ctx))))
}
Expr::Arrow(a) => {
ExprOutput::Expr(Box::alloc().init(Expression::ArrowFunc(a.babelify(ctx))))
}
Expr::Class(c) => {
ExprOutput::Expr(Box::alloc().init(Expression::Class(c.babelify(ctx))))
}
Expr::Yield(y) => {
ExprOutput::Expr(Box::alloc().init(Expression::Yield(y.babelify(ctx))))
}
Expr::MetaProp(m) => {
ExprOutput::Expr(Box::alloc().init(Expression::MetaProp(m.babelify(ctx))))
}
Expr::Await(a) => {
ExprOutput::Expr(Box::alloc().init(Expression::Await(a.babelify(ctx))))
}
Expr::Arrow(a) => ExprOutput::Expr(Box::new(Expression::ArrowFunc(a.babelify(ctx)))),
Expr::Class(c) => ExprOutput::Expr(Box::new(Expression::Class(c.babelify(ctx)))),
Expr::Yield(y) => ExprOutput::Expr(Box::new(Expression::Yield(y.babelify(ctx)))),
Expr::MetaProp(m) => ExprOutput::Expr(Box::new(Expression::MetaProp(m.babelify(ctx)))),
Expr::Await(a) => ExprOutput::Expr(Box::new(Expression::Await(a.babelify(ctx)))),
Expr::Paren(p) => {
ExprOutput::Expr(Box::new(Expression::Parenthesized(p.babelify(ctx))))
ExprOutput::Expr(Box::alloc().init(Expression::Parenthesized(p.babelify(ctx))))
}
Expr::JSXElement(e) => {
ExprOutput::Expr(Box::new(Expression::JSXElement(e.babelify(ctx))))
ExprOutput::Expr(Box::alloc().init(Expression::JSXElement(e.babelify(ctx))))
}
Expr::JSXFragment(f) => {
ExprOutput::Expr(Box::new(Expression::JSXFragment(f.babelify(ctx))))
ExprOutput::Expr(Box::alloc().init(Expression::JSXFragment(f.babelify(ctx))))
}
Expr::TsTypeAssertion(a) => {
ExprOutput::Expr(Box::new(Expression::TSTypeAssertion(a.babelify(ctx))))
ExprOutput::Expr(Box::alloc().init(Expression::TSTypeAssertion(a.babelify(ctx))))
}
Expr::TsNonNull(n) => {
ExprOutput::Expr(Box::new(Expression::TSNonNull(n.babelify(ctx))))
ExprOutput::Expr(Box::alloc().init(Expression::TSNonNull(n.babelify(ctx))))
}
Expr::TsAs(a) => ExprOutput::Expr(Box::new(Expression::TSAs(a.babelify(ctx)))),
Expr::TsAs(a) => ExprOutput::Expr(Box::alloc().init(Expression::TSAs(a.babelify(ctx)))),
Expr::PrivateName(p) => ExprOutput::Private(p.babelify(ctx)),
// TODO(dwoznicki): how does babel handle these?
@ -201,11 +227,7 @@ impl Babelify for ArrayLit {
fn babelify(self, ctx: &Context) -> Self::Output {
ArrayExpression {
base: ctx.base(self.span),
elements: self
.elems
.iter()
.map(|opt| opt.as_ref().map(|el| el.clone().babelify(ctx)))
.collect(),
elements: self.elems.babelify(ctx),
}
}
}
@ -216,11 +238,7 @@ impl Babelify for ObjectLit {
fn babelify(self, ctx: &Context) -> Self::Output {
ObjectExpression {
base: ctx.base(self.span),
properties: self
.props
.iter()
.map(|prop| prop.clone().babelify(ctx))
.collect(),
properties: self.props.babelify(ctx),
}
}
}
@ -248,7 +266,7 @@ impl Babelify for SpreadElement {
fn babelify(self, ctx: &Context) -> Self::Output {
BabelSpreadElement {
base: ctx.base(self.span()),
argument: Box::new(self.expr.babelify(ctx).into()),
argument: Box::alloc().init(self.expr.babelify(ctx).into()),
}
}
}
@ -260,7 +278,7 @@ impl Babelify for UnaryExpr {
UnaryExpression {
base: ctx.base(self.span),
operator: self.op.babelify(ctx),
argument: Box::new(self.arg.babelify(ctx).into()),
argument: Box::alloc().init(self.arg.babelify(ctx).into()),
prefix: true,
}
}
@ -274,7 +292,7 @@ impl Babelify for UpdateExpr {
base: ctx.base(self.span),
operator: self.op.babelify(ctx),
prefix: self.prefix,
argument: Box::new(self.arg.babelify(ctx).into()),
argument: Box::alloc().init(self.arg.babelify(ctx).into()),
}
}
}
@ -294,23 +312,23 @@ impl Babelify for BinExpr {
BinaryOrLogicalExpr::Logical(LogicalExpression {
base: ctx.base(self.span),
operator: self.op.babelify(ctx).into(),
left: Box::new(self.left.babelify(ctx).into()),
right: Box::new(self.right.babelify(ctx).into()),
left: Box::alloc().init(self.left.babelify(ctx).into()),
right: Box::alloc().init(self.right.babelify(ctx).into()),
})
}
_ => BinaryOrLogicalExpr::Binary(BinaryExpression {
base: ctx.base(self.span),
operator: self.op.babelify(ctx).into(),
left: Box::new(self.left.babelify(ctx).into()),
right: Box::new(self.right.babelify(ctx).into()),
left: Box::alloc().init(self.left.babelify(ctx).into()),
right: Box::alloc().init(self.right.babelify(ctx).into()),
}),
}
// BinaryExpression {
// base: ctx.base(self.span),
// operator: self.op.babelify(ctx).into(),
// left: Box::new(self.left.babelify(ctx).into()),
// right: Box::new(self.right.babelify(ctx).into()),
// left: Box::alloc().init(self.left.babelify(ctx).into()),
// right: Box::alloc().init(self.right.babelify(ctx).into()),
// }
}
}
@ -343,9 +361,9 @@ impl Babelify for AssignExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
AssignmentExpression {
base: ctx.base(self.span),
operator: self.op.to_string(),
left: Box::new(self.left.babelify(ctx)),
right: Box::new(self.right.babelify(ctx).into()),
operator: self.op.as_str().into(),
left: Box::alloc().init(self.left.babelify(ctx)),
right: Box::alloc().init(self.right.babelify(ctx).into()),
}
}
}
@ -356,8 +374,8 @@ impl Babelify for MemberExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
MemberExpression {
base: ctx.base(self.span),
object: Box::new(self.obj.babelify(ctx)),
property: Box::new(self.prop.babelify(ctx).into()),
object: Box::alloc().init(self.obj.babelify(ctx)),
property: Box::alloc().init(self.prop.babelify(ctx).into()),
computed: self.computed,
optional: Default::default(),
}
@ -370,9 +388,9 @@ impl Babelify for CondExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
ConditionalExpression {
base: ctx.base(self.span),
test: Box::new(self.test.babelify(ctx).into()),
consequent: Box::new(self.cons.babelify(ctx).into()),
alternate: Box::new(self.alt.babelify(ctx).into()),
test: Box::alloc().init(self.test.babelify(ctx).into()),
consequent: Box::alloc().init(self.cons.babelify(ctx).into()),
alternate: Box::alloc().init(self.alt.babelify(ctx).into()),
}
}
}
@ -383,11 +401,11 @@ impl Babelify for CallExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
CallExpression {
base: ctx.base(self.span),
callee: Box::new(self.callee.babelify(ctx).into()),
callee: Box::alloc().init(self.callee.babelify(ctx).into()),
arguments: self
.args
.iter()
.map(|arg| arg.clone().babelify(ctx).into())
.into_iter()
.map(|arg| arg.babelify(ctx).into())
.collect(),
type_parameters: self.type_args.map(|t| t.babelify(ctx)),
type_arguments: Default::default(),
@ -402,11 +420,11 @@ impl Babelify for NewExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
NewExpression {
base: ctx.base(self.span),
callee: Callee::Expr(Box::new(self.callee.babelify(ctx).into())),
callee: Callee::Expr(Box::alloc().init(self.callee.babelify(ctx).into())),
arguments: match self.args {
Some(args) => args
.iter()
.map(|arg| arg.clone().babelify(ctx).into())
.into_iter()
.map(|arg| arg.babelify(ctx).into())
.collect(),
None => vec![],
},
@ -425,8 +443,8 @@ impl Babelify for SeqExpr {
base: ctx.base(self.span),
expressions: self
.exprs
.iter()
.map(|expr| Box::new(expr.clone().babelify(ctx).into()))
.into_iter()
.map(|expr| Box::alloc().init(expr.babelify(ctx).into()))
.collect(),
}
}
@ -440,15 +458,17 @@ impl Babelify for ArrowExpr {
base: ctx.base(self.span),
params: self
.params
.iter()
.map(|p| p.clone().babelify(ctx).into())
.into_iter()
.map(|p| p.babelify(ctx).into())
.collect(),
body: Box::new(self.body.babelify(ctx)),
body: Box::alloc().init(self.body.babelify(ctx)),
is_async: self.is_async,
generator: self.is_generator,
expression: Default::default(),
type_parameters: self.type_params.map(|t| t.babelify(ctx).into()),
return_type: self.return_type.map(|t| Box::new(t.babelify(ctx).into())),
return_type: self
.return_type
.map(|t| Box::alloc().init(t.babelify(ctx).into())),
}
}
}
@ -459,7 +479,7 @@ impl Babelify for YieldExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
YieldExpression {
base: ctx.base(self.span),
argument: self.arg.map(|a| Box::new(a.babelify(ctx).into())),
argument: self.arg.map(|a| Box::alloc().init(a.babelify(ctx).into())),
delegate: self.delegate,
}
}
@ -483,7 +503,7 @@ impl Babelify for AwaitExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
AwaitExpression {
base: ctx.base(self.span),
argument: Box::new(self.arg.babelify(ctx).into()),
argument: Box::alloc().init(self.arg.babelify(ctx).into()),
}
}
}
@ -496,14 +516,10 @@ impl Babelify for Tpl {
base: ctx.base(self.span),
expressions: self
.exprs
.iter()
.map(|e| TemplateLiteralExpr::Expr(Box::new(e.clone().babelify(ctx).into())))
.collect(),
quasis: self
.quasis
.iter()
.map(|q| q.clone().babelify(ctx))
.into_iter()
.map(|e| TemplateLiteralExpr::Expr(Box::alloc().init(e.babelify(ctx).into())))
.collect(),
quasis: self.quasis.babelify(ctx),
}
}
}
@ -514,7 +530,7 @@ impl Babelify for TaggedTpl {
fn babelify(self, ctx: &Context) -> Self::Output {
TaggedTemplateExpression {
base: ctx.base(self.span),
tag: Box::new(self.tag.babelify(ctx).into()),
tag: Box::alloc().init(self.tag.babelify(ctx).into()),
quasi: self.tpl.babelify(ctx),
type_parameters: self
.type_params
@ -531,8 +547,8 @@ impl Babelify for TplElement {
base: ctx.base(self.span),
tail: self.tail,
value: TemplateElVal {
raw: self.raw.value.to_string(),
cooked: self.cooked.map(|s| s.value.to_string()),
raw: self.raw.value,
cooked: self.cooked.map(|s| s.value),
},
}
}
@ -544,7 +560,7 @@ impl Babelify for ParenExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
ParenthesizedExpression {
base: ctx.base(self.span),
expression: Box::new(self.expr.babelify(ctx).into()),
expression: Box::alloc().init(self.expr.babelify(ctx).into()),
}
}
}
@ -577,9 +593,9 @@ impl Babelify for ExprOrSpread {
match self.spread {
Some(_) => ArrayExprEl::Spread(BabelSpreadElement {
base: ctx.base(self.span()),
argument: Box::new(self.expr.babelify(ctx).into()),
argument: Box::alloc().init(self.expr.babelify(ctx).into()),
}),
None => ArrayExprEl::Expr(Box::new(self.expr.babelify(ctx).into())),
None => ArrayExprEl::Expr(Box::alloc().init(self.expr.babelify(ctx).into())),
}
}
}
@ -590,7 +606,9 @@ impl Babelify for BlockStmtOrExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
match self {
BlockStmtOrExpr::BlockStmt(b) => ArrowFuncExprBody::Block(b.babelify(ctx)),
BlockStmtOrExpr::Expr(e) => ArrowFuncExprBody::Expr(Box::new(e.babelify(ctx).into())),
BlockStmtOrExpr::Expr(e) => {
ArrowFuncExprBody::Expr(Box::alloc().init(e.babelify(ctx).into()))
}
}
}
}
@ -601,6 +619,7 @@ impl Babelify for PatOrExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
match self {
PatOrExpr::Expr(e) => match *e {
Expr::Ident(i) => LVal::Id(i.babelify(ctx)),
Expr::Member(me) => LVal::MemberExpr(me.babelify(ctx)),
_ => panic!("illegal conversion: Cannot convert {:?} to LVal", &e),
},

View File

@ -1,9 +1,9 @@
use crate::{Babelify, Context};
use copyless::BoxHelper;
use swc_babel_ast::{
ArrayPattern, AssignmentPattern, FunctionExpression, Identifier, ObjectPattern,
Param as BabelParam, Pattern, RestElement,
};
use swc_ecma_ast::{Function, Param, ParamOrTsParamProp, Pat};
impl Babelify for Function {
@ -12,16 +12,14 @@ impl Babelify for Function {
fn babelify(self, ctx: &Context) -> Self::Output {
FunctionExpression {
base: ctx.base(self.span),
params: self
.params
.iter()
.map(|param| param.clone().babelify(ctx))
.collect(),
params: self.params.babelify(ctx),
body: self.body.unwrap().babelify(ctx),
generator: Some(self.is_generator),
is_async: Some(self.is_async),
type_parameters: self.type_params.map(|t| t.babelify(ctx).into()),
return_type: self.return_type.map(|t| Box::new(t.babelify(ctx).into())),
return_type: self
.return_type
.map(|t| Box::alloc().init(t.babelify(ctx).into())),
id: None,
}
}
@ -34,52 +32,27 @@ impl Babelify for Param {
match self.pat {
Pat::Ident(i) => BabelParam::Id(Identifier {
base: ctx.base(self.span),
decorators: Some(
self.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
decorators: Some(self.decorators.babelify(ctx)),
..i.babelify(ctx)
}),
Pat::Array(a) => BabelParam::Pat(Pattern::Array(ArrayPattern {
base: ctx.base(self.span),
decorators: Some(
self.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
decorators: Some(self.decorators.babelify(ctx)),
..a.babelify(ctx)
})),
Pat::Rest(r) => BabelParam::Rest(RestElement {
base: ctx.base(self.span),
decorators: Some(
self.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
decorators: Some(self.decorators.babelify(ctx)),
..r.babelify(ctx)
}),
Pat::Object(o) => BabelParam::Pat(Pattern::Object(ObjectPattern {
base: ctx.base(self.span),
decorators: Some(
self.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
decorators: Some(self.decorators.babelify(ctx)),
..o.babelify(ctx)
})),
Pat::Assign(a) => BabelParam::Pat(Pattern::Assignment(AssignmentPattern {
base: ctx.base(self.span),
decorators: Some(
self.decorators
.iter()
.map(|dec| dec.clone().babelify(ctx))
.collect(),
),
decorators: Some(self.decorators.babelify(ctx)),
..a.babelify(ctx)
})),
Pat::Expr(_) => panic!(

View File

@ -1,6 +1,6 @@
use crate::{Babelify, Context};
use copyless::BoxHelper;
use swc_babel_ast::{Identifier, PrivateName as BabelPrivateName};
use swc_ecma_ast::{BindingIdent, Ident, PrivateName};
impl Babelify for BindingIdent {
@ -8,7 +8,9 @@ impl Babelify for BindingIdent {
fn babelify(self, ctx: &Context) -> Self::Output {
Identifier {
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx).into())),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx).into())),
..self.id.babelify(ctx)
}
}
@ -20,7 +22,7 @@ impl Babelify for Ident {
fn babelify(self, ctx: &Context) -> Self::Output {
Identifier {
base: ctx.base(self.span),
name: self.sym.to_string(),
name: self.sym,
optional: Some(self.optional),
decorators: Default::default(),
type_annotation: Default::default(),

View File

@ -1,4 +1,5 @@
use crate::{Babelify, Context};
use copyless::BoxHelper;
use swc_babel_ast::{
JSXAttrName as BabelJSXAttrName, JSXAttrVal, JSXAttribute,
JSXClosingElement as BabelJSXClosingElement, JSXClosingFragment as BabelJSXClosingFragment,
@ -9,7 +10,6 @@ use swc_babel_ast::{
JSXOpeningElement as BabelJSXOpeningElement, JSXOpeningFragment as BabelJSXOpeningFragment,
JSXSpreadAttribute, JSXSpreadChild as BabelJSXSpreadChild, JSXText as BabelJSXText,
};
use swc_common::{BytePos, Span, Spanned};
use swc_ecma_ast::{
JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXClosingElement, JSXClosingFragment,
@ -35,7 +35,7 @@ impl Babelify for JSXMemberExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
JSXMemberExpression {
base: ctx.base(self.span()),
object: Box::new(self.obj.babelify(ctx)),
object: Box::alloc().init(self.obj.babelify(ctx)),
property: self.prop.babelify(ctx).into(),
}
}
@ -80,7 +80,9 @@ impl Babelify for JSXExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
match self {
JSXExpr::JSXEmptyExpr(e) => JSXExprContainerExpr::Empty(e.babelify(ctx)),
JSXExpr::Expr(e) => JSXExprContainerExpr::Expr(Box::new(e.babelify(ctx).into())),
JSXExpr::Expr(e) => {
JSXExprContainerExpr::Expr(Box::alloc().init(e.babelify(ctx).into()))
}
}
}
}
@ -91,7 +93,7 @@ impl Babelify for JSXSpreadChild {
fn babelify(self, ctx: &Context) -> Self::Output {
BabelJSXSpreadChild {
base: ctx.base(self.span),
expression: Box::new(self.expr.babelify(ctx).into()),
expression: Box::alloc().init(self.expr.babelify(ctx).into()),
}
}
}
@ -115,11 +117,7 @@ impl Babelify for JSXOpeningElement {
BabelJSXOpeningElement {
base: ctx.base(self.span),
name: self.name.babelify(ctx),
attributes: self
.attrs
.iter()
.map(|attr| attr.clone().babelify(ctx))
.collect(),
attributes: self.attrs.babelify(ctx),
self_closing: self.self_closing,
type_parameters: self.type_args.map(|arg| arg.babelify(ctx).into()),
}
@ -138,7 +136,7 @@ impl Babelify for JSXAttrOrSpread {
let span = extend_spread_span_to_braces(spread.span(), ctx);
JSXOpeningElAttr::Spread(JSXSpreadAttribute {
base: ctx.base(span),
argument: Box::new(spread.expr.babelify(ctx).into()),
argument: Box::alloc().init(spread.expr.babelify(ctx).into()),
})
}
}
@ -147,7 +145,7 @@ impl Babelify for JSXAttrOrSpread {
fn extend_spread_span_to_braces(sp: Span, ctx: &Context) -> Span {
let mut span = sp;
if let Ok(prev_source) = ctx.cm.span_to_prev_source(sp) {
let _ = ctx.cm.with_span_to_prev_source(sp, |prev_source| {
let mut num_chars = 0;
for c in prev_source.chars().rev() {
num_chars += 1;
@ -157,9 +155,9 @@ fn extend_spread_span_to_braces(sp: Span, ctx: &Context) -> Span {
break;
}
}
}
});
if let Ok(next_source) = ctx.cm.span_to_next_source(sp) {
let _ = ctx.cm.with_span_to_next_source(sp, |next_source| {
let mut num_chars = 0;
for c in next_source.chars() {
num_chars += 1;
@ -169,7 +167,7 @@ fn extend_spread_span_to_braces(sp: Span, ctx: &Context) -> Span {
break;
}
}
}
});
span
}
@ -237,7 +235,7 @@ impl Babelify for JSXText {
fn babelify(self, ctx: &Context) -> Self::Output {
BabelJSXText {
base: ctx.base(self.span),
value: self.value.to_string(),
value: self.value,
}
}
}
@ -251,11 +249,7 @@ impl Babelify for JSXElement {
base: ctx.base(self.span),
opening_element: self.opening.babelify(ctx),
closing_element: self.closing.map(|el| el.babelify(ctx)),
children: self
.children
.iter()
.map(|el| el.clone().babelify(ctx))
.collect(),
children: self.children.babelify(ctx),
self_closing: Some(self_closing),
}
}
@ -283,11 +277,7 @@ impl Babelify for JSXFragment {
base: ctx.base(self.span),
opening_fragment: self.opening.babelify(ctx),
closing_fragment: self.closing.babelify(ctx),
children: self
.children
.iter()
.map(|el| el.clone().babelify(ctx))
.collect(),
children: self.children.babelify(ctx),
}
}
}

View File

@ -1,11 +1,14 @@
#![feature(type_name_of_val)]
use rayon::prelude::*;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::sync::Arc;
use swc::SwcComments;
use swc_babel_ast::{BaseComment, BaseNode, Comment, LineCol, Loc};
use swc_common::comments::CommentKind;
use swc_common::comments::Comments;
use swc_common::sync::Lrc;
use swc_common::BytePos;
use swc_common::SourceFile;
use swc_common::SourceMap;
@ -21,19 +24,18 @@ mod jsx;
mod lit;
mod module;
mod module_decl;
pub mod normalize;
mod operators;
mod pat;
mod prop;
mod stmt;
mod typescript;
pub mod normalize;
#[derive(Clone)]
pub struct Context {
pub fm: Arc<SourceFile>,
pub cm: Arc<SourceMap>,
pub comments: Arc<dyn Comments>,
pub cm: Lrc<SourceMap>,
pub comments: SwcComments,
}
impl Context {
@ -53,7 +55,7 @@ impl Context {
}
fn line_col(&self, pos: BytePos) -> Option<LineCol> {
let loc = self.cm.lookup_char_pos(pos);
let loc = self.cm.lookup_char_pos_with(self.fm.clone(), pos);
Some(LineCol {
line: loc.line,
@ -127,12 +129,42 @@ impl Context {
}
}
pub trait Babelify {
type Output: Serialize + DeserializeOwned;
pub trait Babelify: Send + Sync {
type Output: Serialize + DeserializeOwned + Send + Sync;
fn parallel(_cnt: usize) -> bool {
false
}
fn babelify(self, ctx: &Context) -> Self::Output;
}
impl<T> Babelify for Vec<T>
where
T: Babelify,
{
type Output = Vec<T::Output>;
fn babelify(self, ctx: &Context) -> Self::Output {
if T::parallel(self.len()) {
self.into_par_iter().map(|v| v.babelify(ctx)).collect()
} else {
self.into_iter().map(|v| v.babelify(ctx)).collect()
}
}
}
impl<T> Babelify for Option<T>
where
T: Babelify,
{
type Output = Option<T::Output>;
fn babelify(self, ctx: &Context) -> Self::Output {
self.map(|v| v.babelify(ctx))
}
}
fn extract_class_body_span(class: &Class, ctx: &Context) -> Span {
let sp = ctx.cm.span_take_while(class.span, |ch| *ch != '{');
class.span.with_lo(sp.hi())

View File

@ -35,7 +35,7 @@ impl Babelify for Str {
fn babelify(self, ctx: &Context) -> Self::Output {
StringLiteral {
base: ctx.base(self.span),
value: self.value.to_string(),
value: self.value,
}
}
}
@ -89,8 +89,8 @@ impl Babelify for Regex {
fn babelify(self, ctx: &Context) -> Self::Output {
RegExpLiteral {
base: ctx.base(self.span),
pattern: self.exp.to_string(),
flags: self.flags.to_string(),
pattern: self.exp,
flags: self.flags,
}
}
}

View File

@ -1,14 +1,11 @@
use crate::{Babelify, Context};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use swc::SwcComments;
use swc_babel_ast::{
BaseNode, File, InterpreterDirective, LineCol, Loc, ModuleDeclaration, Program as BabelProgram,
SrcType, Statement,
};
use swc_common::{
comments::{Comment, Comments, CommentsExt},
Span,
};
use swc_common::{comments::Comment, Span};
use swc_ecma_ast::{Invalid, Module, ModuleItem, Program, Script};
use swc_ecma_visit::{Node, Visit, VisitWith};
@ -48,16 +45,16 @@ impl Babelify for Module {
self.span
};
BabelProgram {
base: base_with_trailing_newline(span.clone(), ctx),
base: base_with_trailing_newline(span, ctx),
source_type: SrcType::Module,
body: self
.body
.iter()
.map(|stmt| stmt.clone().babelify(ctx).into())
.into_iter()
.map(|stmt| stmt.babelify(ctx).into())
.collect(),
interpreter: self.shebang.map(|s| InterpreterDirective {
base: ctx.base(extract_shebang_span(span, ctx)),
value: s.to_string(),
value: s,
}),
directives: Default::default(),
source_file: Default::default(),
@ -75,16 +72,12 @@ impl Babelify for Script {
self.span
};
BabelProgram {
base: base_with_trailing_newline(span.clone(), ctx),
base: base_with_trailing_newline(span, ctx),
source_type: SrcType::Script,
body: self
.body
.iter()
.map(|stmt| stmt.clone().babelify(ctx))
.collect(),
body: self.body.babelify(ctx),
interpreter: self.shebang.map(|s| InterpreterDirective {
base: ctx.base(extract_shebang_span(span, ctx)),
value: s.to_string(),
value: s,
}),
directives: Default::default(),
source_file: Default::default(),
@ -114,12 +107,14 @@ fn base_with_trailing_newline(span: Span, ctx: &Context) -> BaseNode {
// line comments. Swc ignores them and starts the program on the next line down,
// while babel includes them in the file start/end.
fn has_comment_first_line(sp: Span, ctx: &Context) -> bool {
ctx.comments.with_leading(sp.hi, |comments| {
if let Some(comments) = ctx.comments.leading.get(&sp.hi) {
!comments
.first()
.map(|c| c.span.lo == ctx.fm.start_pos)
.unwrap_or(false)
})
} else {
true
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -131,6 +126,10 @@ pub enum ModuleItemOutput {
impl Babelify for ModuleItem {
type Output = ModuleItemOutput;
fn parallel(cnt: usize) -> bool {
cnt >= 4
}
fn babelify(self, ctx: &Context) -> Self::Output {
match self {
ModuleItem::ModuleDecl(d) => ModuleItemOutput::ModuleDecl(d.babelify(ctx).into()),
@ -159,7 +158,7 @@ fn extract_shebang_span(span: Span, ctx: &Context) -> Span {
fn extract_all_comments(program: &Program, ctx: &Context) -> Vec<Comment> {
let mut collector = CommentCollector {
comments: Arc::clone(&ctx.comments),
comments: ctx.comments.clone(),
collected: Vec::new(),
};
program.visit_with(
@ -172,7 +171,7 @@ fn extract_all_comments(program: &Program, ctx: &Context) -> Vec<Comment> {
}
struct CommentCollector {
comments: Arc<dyn Comments>,
comments: SwcComments,
collected: Vec<Comment>,
}
@ -182,20 +181,21 @@ impl Visit for CommentCollector {
// Comments must be deduped since it's possible for a single comment to show up
// multiple times since they are not removed from the comments map.
// For example, this happens when the first line in a file is a comment.
self.comments.with_leading(sp.lo, |comments| {
for comment in comments.iter().cloned() {
if !self.collected.iter().any(|c| *c == comment) {
span_comments.push(comment);
if let Some(comments) = self.comments.leading.get(&sp.lo) {
for comment in comments.iter() {
if !self.collected.iter().any(|c| *c == *comment) {
span_comments.push(comment.clone());
}
}
});
self.comments.with_trailing(sp.hi, |comments| {
for comment in comments.iter().cloned() {
if !self.collected.iter().any(|c| *c == comment) {
span_comments.push(comment);
}
if let Some(comments) = self.comments.trailing.get(&sp.hi) {
for comment in comments.iter() {
if !self.collected.iter().any(|c| *c == *comment) {
span_comments.push(comment.clone());
}
}
});
}
self.collected.append(&mut span_comments);
}
}

View File

@ -1,4 +1,6 @@
use crate::{Babelify, Context};
use copyless::BoxHelper;
use serde::{Deserialize, Serialize};
use swc_babel_ast::{
ExportAllDeclaration, ExportDefaultDeclType, ExportDefaultDeclaration,
ExportDefaultSpecifier as BabelExportDefaultSpecifier, ExportKind, ExportNamedDeclaration,
@ -8,8 +10,6 @@ use swc_babel_ast::{
ImportNamespaceSpecifier, ImportSpecifier as BabelImportSpecifier, ImportSpecifierType,
ModuleDeclaration, TSExportAssignment, TSImportEqualsDeclaration, TSNamespaceExportDeclaration,
};
use serde::{Deserialize, Serialize};
use swc_ecma_ast::{
DefaultDecl, ExportAll, ExportDecl, ExportDefaultDecl, ExportDefaultExpr,
ExportDefaultSpecifier, ExportNamedSpecifier, ExportNamespaceSpecifier, ExportSpecifier, Expr,
@ -71,7 +71,9 @@ impl Babelify for ExportDefaultExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
ExportDefaultDeclaration {
base: ctx.base(self.span),
declaration: ExportDefaultDeclType::Expr(Box::new(self.expr.babelify(ctx).into())),
declaration: ExportDefaultDeclType::Expr(
Box::alloc().init(self.expr.babelify(ctx).into()),
),
}
}
}
@ -82,7 +84,7 @@ impl Babelify for ExportDecl {
fn babelify(self, ctx: &Context) -> Self::Output {
ExportNamedDeclaration {
base: ctx.base(self.span),
declaration: Some(Box::new(self.decl.babelify(ctx))),
declaration: Some(Box::alloc().init(self.decl.babelify(ctx))),
specifiers: Default::default(),
source: Default::default(),
assertions: Default::default(),
@ -96,10 +98,12 @@ fn convert_import_asserts(
ctx: &Context,
) -> Option<Vec<ImportAttribute>> {
asserts.map(|obj| {
let obj_span = obj.span;
obj.props
.iter()
.into_iter()
.map(|prop_or_spread| {
let prop = match prop_or_spread.clone() {
let prop = match prop_or_spread {
PropOrSpread::Prop(p) => p,
_ => panic!(
"illegal conversion: Cannot convert {:?} to Prop",
@ -137,7 +141,7 @@ fn convert_import_asserts(
),
};
ImportAttribute {
base: ctx.base(obj.span),
base: ctx.base(obj_span),
key,
value: val,
}
@ -152,11 +156,7 @@ impl Babelify for ImportDecl {
fn babelify(self, ctx: &Context) -> Self::Output {
ImportDeclaration {
base: ctx.base(self.span),
specifiers: self
.specifiers
.iter()
.map(|spec| spec.clone().babelify(ctx))
.collect(),
specifiers: self.specifiers.babelify(ctx),
source: self.src.babelify(ctx),
assertions: convert_import_asserts(self.asserts, ctx),
import_kind: if self.type_only {
@ -188,11 +188,7 @@ impl Babelify for NamedExport {
ExportNamedDeclaration {
base: ctx.base(self.span),
declaration: Default::default(),
specifiers: self
.specifiers
.iter()
.map(|spec| spec.clone().babelify(ctx))
.collect(),
specifiers: self.specifiers.babelify(ctx),
source: self.src.map(|s| s.babelify(ctx)),
assertions: convert_import_asserts(self.asserts, ctx),
export_kind: if self.type_only {

View File

@ -1,3 +1,4 @@
use swc_atoms::js_word;
use swc_babel_ast::*;
use swc_babel_visit::{VisitMut, VisitMutWith};
@ -136,7 +137,7 @@ impl VisitMut for Normalizer {
fn visit_mut_jsx_text(&mut self, node: &mut JSXText) {
if node.value.trim().is_empty() {
node.value = "".to_owned();
node.value = js_word!("");
}
node.visit_mut_children_with(self);
}

View File

@ -1,11 +1,11 @@
use crate::{Babelify, Context};
use copyless::BoxHelper;
use serde::{Deserialize, Serialize};
use swc_babel_ast::{
ArrayPattern, AssignmentPattern, AssignmentPatternLeft, CatchClauseParam, Expression,
Identifier, LVal, ObjectKey, ObjectPattern, ObjectPatternProp, ObjectPropVal, ObjectProperty,
Param, Pattern, PatternLike, RestElement,
};
use serde::{Deserialize, Serialize};
use swc_common::Spanned;
use swc_ecma_ast::{
ArrayPat, AssignPat, AssignPatProp, KeyValuePatProp, ObjectPat, ObjectPatProp, Pat, RestPat,
@ -31,7 +31,7 @@ impl Babelify for Pat {
Pat::Rest(r) => PatOutput::Rest(r.babelify(ctx)),
Pat::Object(o) => PatOutput::Object(o.babelify(ctx)),
Pat::Assign(a) => PatOutput::Assign(a.babelify(ctx)),
Pat::Expr(e) => PatOutput::Expr(Box::new(e.babelify(ctx).into())),
Pat::Expr(e) => PatOutput::Expr(Box::alloc().init(e.babelify(ctx).into())),
Pat::Invalid(_) => panic!(
"illegal conversion: Cannot convert {:?} to PatOutput",
&self
@ -55,7 +55,7 @@ impl From<PatOutput> for ObjectPropVal {
fn from(pat: PatOutput) -> Self {
match pat {
PatOutput::Expr(e) => ObjectPropVal::Expr(e),
other => other.into(),
other => ObjectPropVal::Pattern(other.into()),
}
}
}
@ -146,10 +146,12 @@ impl Babelify for ArrayPat {
base: ctx.base(self.span),
elements: self
.elems
.iter()
.map(|opt| opt.as_ref().map(|e| e.clone().babelify(ctx).into()))
.into_iter()
.map(|opt| opt.map(|e| e.babelify(ctx).into()))
.collect(),
type_annotation: self.type_ann.map(|a| Box::new(a.babelify(ctx).into())),
type_annotation: self
.type_ann
.map(|a| Box::alloc().init(a.babelify(ctx).into())),
decorators: Default::default(),
}
}
@ -161,8 +163,10 @@ impl Babelify for ObjectPat {
fn babelify(self, ctx: &Context) -> Self::Output {
ObjectPattern {
base: ctx.base(self.span),
properties: self.props.iter().map(|p| p.clone().babelify(ctx)).collect(),
type_annotation: self.type_ann.map(|a| Box::new(a.babelify(ctx).into())),
properties: self.props.babelify(ctx),
type_annotation: self
.type_ann
.map(|a| Box::alloc().init(a.babelify(ctx).into())),
decorators: Default::default(),
}
}
@ -186,7 +190,7 @@ impl Babelify for KeyValuePatProp {
fn babelify(self, ctx: &Context) -> Self::Output {
ObjectProperty {
base: ctx.base(self.span()),
key: self.key.babelify(ctx).into(),
key: self.key.babelify(ctx),
value: self.value.babelify(ctx).into(),
computed: Default::default(),
shorthand: Default::default(),
@ -201,8 +205,10 @@ impl Babelify for RestPat {
fn babelify(self, ctx: &Context) -> Self::Output {
RestElement {
base: ctx.base(self.span),
argument: Box::new(self.arg.babelify(ctx).into()),
type_annotation: self.type_ann.map(|a| Box::new(a.babelify(ctx).into())),
argument: Box::alloc().init(self.arg.babelify(ctx).into()),
type_annotation: self
.type_ann
.map(|a| Box::alloc().init(a.babelify(ctx).into())),
decorators: Default::default(),
}
}
@ -215,8 +221,10 @@ impl Babelify for AssignPat {
AssignmentPattern {
base: ctx.base(self.span),
left: self.left.babelify(ctx).into(),
right: Box::new(self.right.babelify(ctx).into()),
type_annotation: self.type_ann.map(|a| Box::new(a.babelify(ctx).into())),
right: Box::alloc().init(self.right.babelify(ctx).into()),
type_annotation: self
.type_ann
.map(|a| Box::alloc().init(a.babelify(ctx).into())),
decorators: Default::default(),
}
}
@ -233,7 +241,7 @@ impl Babelify for AssignPatProp {
value: if is_shorthand {
ObjectPropVal::Pattern(PatternLike::Id(self.key.babelify(ctx)))
} else {
ObjectPropVal::Expr(Box::new(self.value.unwrap().babelify(ctx).into()))
ObjectPropVal::Expr(Box::alloc().init(self.value.unwrap().babelify(ctx).into()))
},
shorthand: is_shorthand,
computed: Default::default(),

View File

@ -1,9 +1,9 @@
use crate::{Babelify, Context};
use copyless::BoxHelper;
use swc_babel_ast::{
AssignmentPattern, AssignmentPatternLeft, Expression, FunctionExpression, ObjectKey,
ObjectMember, ObjectMethod, ObjectMethodKind, ObjectPropVal, ObjectProperty,
};
use swc_common::Spanned;
use swc_ecma_ast::{
AssignProp, ComputedPropName, GetterProp, KeyValueProp, MethodProp, Prop, PropName, SetterProp,
@ -19,7 +19,7 @@ impl Babelify for Prop {
ObjectMember::Prop(ObjectProperty {
base: id.base.clone(),
key: ObjectKey::Id(id.clone()),
value: ObjectPropVal::Expr(Box::new(Expression::Id(id))),
value: ObjectPropVal::Expr(Box::alloc().init(Expression::Id(id))),
computed: Default::default(),
shorthand: true,
decorators: Default::default(),
@ -44,7 +44,7 @@ impl Babelify for KeyValueProp {
ObjectProperty {
base: ctx.base(self.span()),
key: self.key.babelify(ctx),
value: ObjectPropVal::Expr(Box::new(self.value.babelify(ctx).into())),
value: ObjectPropVal::Expr(Box::alloc().init(self.value.babelify(ctx).into())),
computed: Default::default(),
shorthand: Default::default(),
decorators: Default::default(),
@ -61,7 +61,7 @@ impl Babelify for AssignProp {
AssignmentPattern {
base: ctx.base(self.span()),
left: AssignmentPatternLeft::Id(self.key.babelify(ctx)),
right: Box::new(self.value.babelify(ctx).into()),
right: Box::alloc().init(self.value.babelify(ctx).into()),
decorators: Default::default(),
type_annotation: Default::default(),
}
@ -76,7 +76,9 @@ impl Babelify for GetterProp {
base: ctx.base(self.span),
kind: ObjectMethodKind::Get,
key: self.key.babelify(ctx),
return_type: self.type_ann.map(|ann| Box::new(ann.babelify(ctx).into())),
return_type: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx).into())),
body: self.body.unwrap().babelify(ctx),
params: Default::default(),
computed: Default::default(),
@ -137,7 +139,7 @@ impl Babelify for PropName {
PropName::Ident(i) => ObjectKey::Id(i.babelify(ctx)),
PropName::Str(s) => ObjectKey::String(s.babelify(ctx)),
PropName::Num(n) => ObjectKey::Numeric(n.babelify(ctx)),
PropName::Computed(e) => ObjectKey::Expr(Box::new(e.babelify(ctx))),
PropName::Computed(e) => ObjectKey::Expr(Box::alloc().init(e.babelify(ctx))),
_ => panic!(
"illegal conversion: Cannot convert {:?} to ObjectKey",
&self

View File

@ -1,4 +1,5 @@
use crate::{Babelify, Context};
use copyless::BoxHelper;
use swc_babel_ast::{
BlockStatement, BreakStatement, CatchClause as BabelCatchClause, ContinueStatement,
DebuggerStatement, DoWhileStatement, EmptyStatement, ExpressionStatement, ForInStatement,
@ -6,7 +7,6 @@ use swc_babel_ast::{
ReturnStatement, Statement, SwitchCase as BabelSwitchCase, SwitchStatement, ThrowStatement,
TryStatement, WhileStatement, WithStatement,
};
use swc_ecma_ast::{
BlockStmt, BreakStmt, CatchClause, ContinueStmt, DebuggerStmt, Decl, DoWhileStmt, EmptyStmt,
ExprStmt, ForInStmt, ForOfStmt, ForStmt, IfStmt, LabeledStmt, ReturnStmt, Stmt, SwitchCase,
@ -19,11 +19,7 @@ impl Babelify for BlockStmt {
fn babelify(self, ctx: &Context) -> Self::Output {
BlockStatement {
base: ctx.base(self.span),
body: self
.stmts
.iter()
.map(|stmt| stmt.clone().babelify(ctx))
.collect(),
body: self.stmts.babelify(ctx),
directives: Default::default(),
}
}
@ -32,6 +28,10 @@ impl Babelify for BlockStmt {
impl Babelify for Stmt {
type Output = Statement;
fn parallel(cnt: usize) -> bool {
cnt >= 16
}
fn babelify(self, ctx: &Context) -> Self::Output {
match self {
Stmt::Block(s) => Statement::Block(s.babelify(ctx)),
@ -71,7 +71,7 @@ impl Babelify for ExprStmt {
fn babelify(self, ctx: &Context) -> Self::Output {
ExpressionStatement {
base: ctx.base(self.span),
expression: Box::new(self.expr.babelify(ctx).into()),
expression: Box::alloc().init(self.expr.babelify(ctx).into()),
}
}
}
@ -102,8 +102,8 @@ impl Babelify for WithStmt {
fn babelify(self, ctx: &Context) -> Self::Output {
WithStatement {
base: ctx.base(self.span),
object: Box::new(self.obj.babelify(ctx).into()),
body: Box::new(self.body.babelify(ctx)),
object: Box::alloc().init(self.obj.babelify(ctx).into()),
body: Box::alloc().init(self.body.babelify(ctx)),
}
}
}
@ -114,7 +114,9 @@ impl Babelify for ReturnStmt {
fn babelify(self, ctx: &Context) -> Self::Output {
ReturnStatement {
base: ctx.base(self.span),
argument: self.arg.map(|expr| Box::new(expr.babelify(ctx).into())),
argument: self
.arg
.map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
}
}
}
@ -126,7 +128,7 @@ impl Babelify for LabeledStmt {
LabeledStatement {
base: ctx.base(self.span),
label: self.label.babelify(ctx),
body: Box::new(self.body.babelify(ctx)),
body: Box::alloc().init(self.body.babelify(ctx)),
}
}
}
@ -159,9 +161,9 @@ impl Babelify for IfStmt {
fn babelify(self, ctx: &Context) -> Self::Output {
IfStatement {
base: ctx.base(self.span),
test: Box::new(self.test.babelify(ctx).into()),
consequent: Box::new(self.cons.babelify(ctx)),
alternate: self.alt.map(|a| Box::new(a.babelify(ctx))),
test: Box::alloc().init(self.test.babelify(ctx).into()),
consequent: Box::alloc().init(self.cons.babelify(ctx)),
alternate: self.alt.map(|a| Box::alloc().init(a.babelify(ctx))),
}
}
}
@ -172,12 +174,8 @@ impl Babelify for SwitchStmt {
fn babelify(self, ctx: &Context) -> Self::Output {
SwitchStatement {
base: ctx.base(self.span),
discriminant: Box::new(self.discriminant.babelify(ctx).into()),
cases: self
.cases
.iter()
.map(|case| case.clone().babelify(ctx))
.collect(),
discriminant: Box::alloc().init(self.discriminant.babelify(ctx).into()),
cases: self.cases.babelify(ctx),
}
}
}
@ -188,7 +186,7 @@ impl Babelify for ThrowStmt {
fn babelify(self, ctx: &Context) -> Self::Output {
ThrowStatement {
base: ctx.base(self.span),
argument: Box::new(self.arg.babelify(ctx).into()),
argument: Box::alloc().init(self.arg.babelify(ctx).into()),
}
}
}
@ -212,8 +210,8 @@ impl Babelify for WhileStmt {
fn babelify(self, ctx: &Context) -> Self::Output {
WhileStatement {
base: ctx.base(self.span),
test: Box::new(self.test.babelify(ctx).into()),
body: Box::new(self.body.babelify(ctx)),
test: Box::alloc().init(self.test.babelify(ctx).into()),
body: Box::alloc().init(self.body.babelify(ctx)),
}
}
}
@ -224,8 +222,8 @@ impl Babelify for DoWhileStmt {
fn babelify(self, ctx: &Context) -> Self::Output {
DoWhileStatement {
base: ctx.base(self.span),
test: Box::new(self.test.babelify(ctx).into()),
body: Box::new(self.body.babelify(ctx)),
test: Box::alloc().init(self.test.babelify(ctx).into()),
body: Box::alloc().init(self.body.babelify(ctx)),
}
}
}
@ -237,9 +235,13 @@ impl Babelify for ForStmt {
ForStatement {
base: ctx.base(self.span),
init: self.init.map(|i| i.babelify(ctx)),
test: self.test.map(|expr| Box::new(expr.babelify(ctx).into())),
update: self.update.map(|expr| Box::new(expr.babelify(ctx).into())),
body: Box::new(self.body.babelify(ctx)),
test: self
.test
.map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
update: self
.update
.map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
body: Box::alloc().init(self.body.babelify(ctx)),
}
}
}
@ -251,8 +253,8 @@ impl Babelify for ForInStmt {
ForInStatement {
base: ctx.base(self.span),
left: self.left.babelify(ctx),
right: Box::new(self.right.babelify(ctx).into()),
body: Box::new(self.body.babelify(ctx)),
right: Box::alloc().init(self.right.babelify(ctx).into()),
body: Box::alloc().init(self.body.babelify(ctx)),
}
}
}
@ -264,8 +266,8 @@ impl Babelify for ForOfStmt {
ForOfStatement {
base: ctx.base(self.span),
left: self.left.babelify(ctx),
right: Box::new(self.right.babelify(ctx).into()),
body: Box::new(self.body.babelify(ctx)),
right: Box::alloc().init(self.right.babelify(ctx).into()),
body: Box::alloc().init(self.body.babelify(ctx)),
// await_token not yet implemented
}
}
@ -277,12 +279,10 @@ impl Babelify for SwitchCase {
fn babelify(self, ctx: &Context) -> Self::Output {
BabelSwitchCase {
base: ctx.base(self.span),
test: self.test.map(|expr| Box::new(expr.babelify(ctx).into())),
consequent: self
.cons
.iter()
.map(|stmt| stmt.clone().babelify(ctx))
.collect(),
test: self
.test
.map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
consequent: self.cons.babelify(ctx),
}
}
}
@ -316,7 +316,7 @@ impl Babelify for VarDeclOrExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
match self {
VarDeclOrExpr::VarDecl(v) => ForStmtInit::VarDecl(v.babelify(ctx)),
VarDeclOrExpr::Expr(e) => ForStmtInit::Expr(Box::new(e.babelify(ctx).into())),
VarDeclOrExpr::Expr(e) => ForStmtInit::Expr(Box::alloc().init(e.babelify(ctx).into())),
}
}
}

View File

@ -1,4 +1,7 @@
use crate::{Babelify, Context};
use copyless::BoxHelper;
use swc_atoms::js_word;
use swc_atoms::JsWord;
use swc_babel_ast::{
Access, ArrayPattern, IdOrRest, IdOrString, Identifier, ObjectPattern, RestElement,
TSAnyKeyword, TSArrayType, TSAsExpression, TSBigIntKeyword, TSBooleanKeyword,
@ -56,11 +59,11 @@ impl Babelify for TsFnType {
base: ctx.base(self.span),
parameters: self
.params
.iter()
.map(|p| p.clone().babelify(ctx).into())
.into_iter()
.map(|p| p.babelify(ctx).into())
.collect(),
type_parameters: self.type_params.map(|decl| decl.babelify(ctx)),
type_annotation: Some(Box::new(self.type_ann.babelify(ctx))),
type_parameters: self.type_params.babelify(ctx),
type_annotation: Some(Box::alloc().init(self.type_ann.babelify(ctx))),
}
}
}
@ -111,11 +114,7 @@ impl Babelify for TsTypeParamDecl {
fn babelify(self, ctx: &Context) -> Self::Output {
TSTypeParameterDeclaration {
base: ctx.base(self.span),
params: self
.params
.iter()
.map(|p| p.clone().babelify(ctx))
.collect(),
params: self.params.babelify(ctx),
}
}
}
@ -126,9 +125,9 @@ impl Babelify for TsTypeParam {
fn babelify(self, ctx: &Context) -> Self::Output {
TSTypeParameter {
base: ctx.base(self.span),
name: self.name.sym.to_string(),
constraint: self.constraint.map(|c| Box::new(c.babelify(ctx))),
default: self.default.map(|d| Box::new(d.babelify(ctx))),
name: self.name.sym,
constraint: self.constraint.map(|c| Box::alloc().init(c.babelify(ctx))),
default: self.default.map(|d| Box::alloc().init(d.babelify(ctx))),
}
}
}
@ -139,11 +138,7 @@ impl Babelify for TsTypeParamInstantiation {
fn babelify(self, ctx: &Context) -> Self::Output {
TSTypeParameterInstantiation {
base: ctx.base(self.span),
params: self
.params
.iter()
.map(|param| param.clone().babelify(ctx))
.collect(),
params: self.params.into_iter().map(|v| v.babelify(ctx)).collect(),
}
}
}
@ -178,7 +173,7 @@ impl Babelify for TsQualifiedName {
fn babelify(self, ctx: &Context) -> Self::Output {
TSQualifiedName {
base: ctx.base(self.span()),
left: Box::new(self.left.babelify(ctx)),
left: Box::alloc().init(self.left.babelify(ctx)),
right: self.right.babelify(ctx),
}
}
@ -224,10 +219,12 @@ impl Babelify for TsCallSignatureDecl {
type_parameters: self.type_params.map(|t| t.babelify(ctx)),
parameters: self
.params
.iter()
.map(|param| param.clone().babelify(ctx).into())
.into_iter()
.map(|param| param.babelify(ctx).into())
.collect(),
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx))),
}
}
}
@ -241,10 +238,12 @@ impl Babelify for TsConstructSignatureDecl {
type_parameters: self.type_params.map(|t| t.babelify(ctx)),
parameters: self
.params
.iter()
.map(|param| param.clone().babelify(ctx).into())
.into_iter()
.map(|param| param.babelify(ctx).into())
.collect(),
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx))),
}
}
}
@ -255,9 +254,11 @@ impl Babelify for TsPropertySignature {
fn babelify(self, ctx: &Context) -> Self::Output {
TSPropertySignature {
base: ctx.base(self.span),
key: Box::new(self.key.babelify(ctx).into()),
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))),
initializer: self.init.map(|i| Box::new(i.babelify(ctx).into())),
key: Box::alloc().init(self.key.babelify(ctx).into()),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx))),
initializer: self.init.map(|i| Box::alloc().init(i.babelify(ctx).into())),
computed: Some(self.computed),
optional: Some(self.optional),
readonly: Some(self.readonly),
@ -271,14 +272,16 @@ impl Babelify for TsMethodSignature {
fn babelify(self, ctx: &Context) -> Self::Output {
TSMethodSignature {
base: ctx.base(self.span),
key: Box::new(self.key.babelify(ctx).into()),
key: Box::alloc().init(self.key.babelify(ctx).into()),
type_parameters: self.type_params.map(|t| t.babelify(ctx)),
parameters: self
.params
.iter()
.map(|param| param.clone().babelify(ctx).into())
.into_iter()
.map(|param| param.babelify(ctx).into())
.collect(),
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx))),
computed: Some(self.computed),
optional: Some(self.optional),
}
@ -293,10 +296,12 @@ impl Babelify for TsIndexSignature {
base: ctx.base(self.span),
paramters: self
.params
.iter()
.map(|param| param.clone().babelify(ctx).into())
.into_iter()
.map(|param| param.babelify(ctx).into())
.collect(),
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx))),
readonly: Some(self.readonly),
}
}
@ -459,11 +464,11 @@ impl Babelify for TsConstructorType {
base: ctx.base(self.span),
parameters: self
.params
.iter()
.map(|param| param.clone().babelify(ctx).into())
.into_iter()
.map(|param| param.babelify(ctx).into())
.collect(),
type_parameters: self.type_params.map(|decl| decl.babelify(ctx)),
type_annotation: Some(Box::new(self.type_ann.babelify(ctx))),
type_annotation: Some(Box::alloc().init(self.type_ann.babelify(ctx))),
is_abstract: Some(self.is_abstract),
}
}
@ -488,7 +493,9 @@ impl Babelify for TsTypePredicate {
TSTypePredicate {
base: ctx.base(self.span),
parameter_name: self.param_name.babelify(ctx),
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx))),
asserts: Some(self.asserts),
}
}
@ -546,11 +553,7 @@ impl Babelify for TsTypeLit {
fn babelify(self, ctx: &Context) -> Self::Output {
TSTypeLiteral {
base: ctx.base(self.span),
members: self
.members
.iter()
.map(|memb| memb.clone().babelify(ctx))
.collect(),
members: self.members.babelify(ctx),
}
}
}
@ -561,7 +564,7 @@ impl Babelify for TsArrayType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSArrayType {
base: ctx.base(self.span),
element_type: Box::new(self.elem_type.babelify(ctx)),
element_type: Box::alloc().init(self.elem_type.babelify(ctx)),
}
}
}
@ -572,11 +575,7 @@ impl Babelify for TsTupleType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSTupleType {
base: ctx.base(self.span),
element_types: self
.elem_types
.iter()
.map(|t| t.clone().babelify(ctx))
.collect(),
element_types: self.elem_types.babelify(ctx),
}
}
}
@ -616,7 +615,7 @@ impl Babelify for TsOptionalType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSOptionalType {
base: ctx.base(self.span),
type_annotation: Box::new(self.type_ann.babelify(ctx)),
type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)),
}
}
}
@ -627,7 +626,7 @@ impl Babelify for TsRestType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSRestType {
base: ctx.base(self.span),
type_annotation: Box::new(self.type_ann.babelify(ctx)),
type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)),
}
}
}
@ -659,7 +658,7 @@ impl Babelify for TsUnionType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSUnionType {
base: ctx.base(self.span),
types: self.types.iter().map(|t| t.clone().babelify(ctx)).collect(),
types: self.types.into_iter().map(|t| t.babelify(ctx)).collect(),
}
}
}
@ -670,7 +669,7 @@ impl Babelify for TsIntersectionType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSIntersectionType {
base: ctx.base(self.span),
types: self.types.iter().map(|t| t.clone().babelify(ctx)).collect(),
types: self.types.into_iter().map(|t| t.babelify(ctx)).collect(),
}
}
}
@ -681,10 +680,10 @@ impl Babelify for TsConditionalType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSConditionalType {
base: ctx.base(self.span),
check_type: Box::new(self.check_type.babelify(ctx)),
extends_type: Box::new(self.extends_type.babelify(ctx)),
true_type: Box::new(self.true_type.babelify(ctx)),
false_type: Box::new(self.false_type.babelify(ctx)),
check_type: Box::alloc().init(self.check_type.babelify(ctx)),
extends_type: Box::alloc().init(self.extends_type.babelify(ctx)),
true_type: Box::alloc().init(self.true_type.babelify(ctx)),
false_type: Box::alloc().init(self.false_type.babelify(ctx)),
}
}
}
@ -695,7 +694,7 @@ impl Babelify for TsInferType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSInferType {
base: ctx.base(self.span),
type_parameter: Box::new(self.type_param.babelify(ctx)),
type_parameter: Box::alloc().init(self.type_param.babelify(ctx)),
}
}
}
@ -706,7 +705,7 @@ impl Babelify for TsParenthesizedType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSParenthesizedType {
base: ctx.base(self.span),
type_annotation: Box::new(self.type_ann.babelify(ctx)),
type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)),
}
}
}
@ -717,20 +716,20 @@ impl Babelify for TsTypeOperator {
fn babelify(self, ctx: &Context) -> Self::Output {
TSTypeOperator {
base: ctx.base(self.span),
type_annotation: Box::new(self.type_ann.babelify(ctx)),
type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)),
operator: self.op.babelify(ctx),
}
}
}
impl Babelify for TsTypeOperatorOp {
type Output = String;
type Output = JsWord;
fn babelify(self, _ctx: &Context) -> Self::Output {
match self {
TsTypeOperatorOp::KeyOf => "keyof".to_string(),
TsTypeOperatorOp::Unique => "unique".to_string(),
TsTypeOperatorOp::ReadOnly => "readonly".to_string(),
TsTypeOperatorOp::KeyOf => js_word!("keyof"),
TsTypeOperatorOp::Unique => js_word!("unique"),
TsTypeOperatorOp::ReadOnly => js_word!("readonly"),
}
}
}
@ -741,8 +740,8 @@ impl Babelify for TsIndexedAccessType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSIndexedAccessType {
base: ctx.base(self.span),
object_type: Box::new(self.obj_type.babelify(ctx)),
index_type: Box::new(self.index_type.babelify(ctx)),
object_type: Box::alloc().init(self.obj_type.babelify(ctx)),
index_type: Box::alloc().init(self.index_type.babelify(ctx)),
}
}
}
@ -755,9 +754,11 @@ impl Babelify for TsMappedType {
fn babelify(self, ctx: &Context) -> Self::Output {
TSMappedType {
base: ctx.base(self.span),
type_parameter: Box::new(self.type_param.babelify(ctx)),
type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))),
name_type: self.name_type.map(|t| Box::new(t.babelify(ctx))),
type_parameter: Box::alloc().init(self.type_param.babelify(ctx)),
type_annotation: self
.type_ann
.map(|ann| Box::alloc().init(ann.babelify(ctx))),
name_type: self.name_type.map(|t| Box::alloc().init(t.babelify(ctx))),
optional: self.optional.map(|val| val == TruePlusMinus::True),
readonly: self.readonly.map(|val| val == TruePlusMinus::True),
}
@ -810,7 +811,7 @@ impl Babelify for TsInterfaceDecl {
base: ctx.base(self.span),
id: self.id.babelify(ctx),
type_parameters: self.type_params.map(|t| t.babelify(ctx)),
extends: self.extends.first().map(|ext| ext.clone().babelify(ctx)),
extends: self.extends.into_iter().next().babelify(ctx),
body: self.body.babelify(ctx),
declare: Some(self.declare),
}
@ -823,11 +824,7 @@ impl Babelify for TsInterfaceBody {
fn babelify(self, ctx: &Context) -> Self::Output {
TSInterfaceBody {
base: ctx.base(self.span),
body: self
.body
.iter()
.map(|el| el.clone().babelify(ctx))
.collect(),
body: self.body.babelify(ctx),
}
}
}
@ -865,11 +862,7 @@ impl Babelify for TsEnumDecl {
TSEnumDeclaration {
base: ctx.base(self.span),
id: self.id.babelify(ctx),
members: self
.members
.iter()
.map(|memb| memb.clone().babelify(ctx))
.collect(),
members: self.members.babelify(ctx),
is_const: Some(self.is_const),
declare: Some(self.declare),
initializer: Default::default(),
@ -884,7 +877,7 @@ impl Babelify for TsEnumMember {
TSEnumMember {
base: ctx.base(self.span),
id: self.id.babelify(ctx),
initializer: self.init.map(|i| Box::new(i.babelify(ctx).into())),
initializer: self.init.map(|i| Box::alloc().init(i.babelify(ctx).into())),
}
}
}
@ -907,7 +900,7 @@ impl Babelify for TsModuleDecl {
TSModuleDeclaration {
base: ctx.base(self.span),
id: self.id.babelify(ctx),
body: Box::new(self.body.unwrap().babelify(ctx)),
body: Box::alloc().init(self.body.unwrap().babelify(ctx)),
declare: Some(self.declare),
global: Some(self.global),
}
@ -933,8 +926,8 @@ impl Babelify for TsModuleBlock {
base: ctx.base(self.span),
body: self
.body
.iter()
.map(|m| m.clone().babelify(ctx).into())
.into_iter()
.map(|m| m.babelify(ctx).into())
.collect(),
}
}
@ -947,7 +940,7 @@ impl Babelify for TsNamespaceDecl {
TSModuleDeclaration {
base: ctx.base(self.span),
id: IdOrString::Id(self.id.babelify(ctx)),
body: Box::new(self.body.babelify(ctx)),
body: Box::alloc().init(self.body.babelify(ctx)),
declare: Some(self.declare),
global: Some(self.global),
}
@ -1008,7 +1001,7 @@ impl Babelify for TsExportAssignment {
fn babelify(self, ctx: &Context) -> Self::Output {
TSExportAssignment {
base: ctx.base(self.span),
expression: Box::new(self.expr.babelify(ctx).into()),
expression: Box::alloc().init(self.expr.babelify(ctx).into()),
}
}
}
@ -1030,7 +1023,7 @@ impl Babelify for TsAsExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
TSAsExpression {
base: ctx.base(self.span),
expression: Box::new(self.expr.babelify(ctx).into()),
expression: Box::alloc().init(self.expr.babelify(ctx).into()),
type_annotation: self.type_ann.babelify(ctx),
}
}
@ -1042,7 +1035,7 @@ impl Babelify for TsTypeAssertion {
fn babelify(self, ctx: &Context) -> Self::Output {
TSTypeAssertion {
base: ctx.base(self.span),
expression: Box::new(self.expr.babelify(ctx).into()),
expression: Box::alloc().init(self.expr.babelify(ctx).into()),
type_annotation: self.type_ann.babelify(ctx),
}
}
@ -1054,7 +1047,7 @@ impl Babelify for TsNonNullExpr {
fn babelify(self, ctx: &Context) -> Self::Output {
TSNonNullExpression {
base: ctx.base(self.span),
expression: Box::new(self.expr.babelify(ctx).into()),
expression: Box::alloc().init(self.expr.babelify(ctx).into()),
}
}
}

View File

@ -2,6 +2,7 @@
extern crate test;
use anyhow::{Context as AnyhowContext, Error};
use copyless::BoxHelper;
use pretty_assertions::assert_eq;
use std::{
env, fs,
@ -27,9 +28,7 @@ use walkdir::WalkDir;
fn fixtures() -> Result<(), Error> {
let mut tests = vec![];
let fixtures_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?)
.join("tests")
.join("fixtures");
let fixtures_path = PathBuf::from("tests").join("fixtures");
for entry in WalkDir::new(&fixtures_path).into_iter() {
let entry = entry.with_context(|| "Failed to walk dir")?;
if !entry.file_type().is_dir() {
@ -76,7 +75,7 @@ fn fixtures() -> Result<(), Error> {
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move || {
testfn: DynTestFn(Box::alloc().init(move || {
let syntax = if is_typescript {
Syntax::Typescript(Default::default())
} else if is_jsx {
@ -143,10 +142,11 @@ fn run_test(src: String, expected: String, syntax: Syntax, is_module: bool) {
let ctx = Context {
fm,
cm,
comments: Arc::new(compiler.comments().clone()),
comments: compiler.comments().clone(),
};
let mut ast = swc_ast.babelify(&ctx);
normalize(&mut ast);
println!("Actaul: {:?}", ast);
let mut expected_ast: File = serde_json::from_str(&expected).unwrap();
normalize(&mut expected_ast);

Some files were not shown because too many files have changed in this diff Show More