mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(codegen): improve codegen formatting (#3735)
This commit is contained in:
parent
4d462636cb
commit
5a99d30eba
6 changed files with 4789 additions and 4744 deletions
|
|
@ -193,45 +193,46 @@ fn print_if<const MINIFY: bool>(
|
|||
p.print(b'(');
|
||||
p.print_expression(&if_stmt.test);
|
||||
p.print(b')');
|
||||
p.print_soft_space();
|
||||
|
||||
match &if_stmt.consequent {
|
||||
Statement::BlockStatement(block) => {
|
||||
p.print_soft_space();
|
||||
p.print_block_statement(block, ctx);
|
||||
if if_stmt.alternate.is_some() {
|
||||
p.print_soft_space();
|
||||
} else {
|
||||
p.print_soft_newline();
|
||||
}
|
||||
}
|
||||
stmt if wrap_to_avoid_ambiguous_else(stmt) => {
|
||||
p.print_soft_space();
|
||||
p.print_block_start(stmt.span().start);
|
||||
stmt.gen(p, ctx);
|
||||
p.needs_semicolon = false;
|
||||
p.print_block_end(stmt.span().end);
|
||||
if if_stmt.alternate.is_some() {
|
||||
p.print_soft_space();
|
||||
} else {
|
||||
p.print_soft_newline();
|
||||
}
|
||||
}
|
||||
stmt => {
|
||||
stmt.gen(p, ctx);
|
||||
}
|
||||
}
|
||||
if if_stmt.alternate.is_some() {
|
||||
p.print_soft_space();
|
||||
} else {
|
||||
p.print_soft_newline();
|
||||
stmt => p.print_body(stmt, false, ctx),
|
||||
}
|
||||
if let Some(alternate) = if_stmt.alternate.as_ref() {
|
||||
p.print_semicolon_if_needed();
|
||||
p.print_space_before_identifier();
|
||||
p.print_str(b"else ");
|
||||
p.print_str(b"else");
|
||||
match alternate {
|
||||
Statement::BlockStatement(block) => {
|
||||
p.print_soft_space();
|
||||
p.print_block_statement(block, ctx);
|
||||
p.print_soft_newline();
|
||||
}
|
||||
Statement::IfStatement(if_stmt) => {
|
||||
p.print_hard_space();
|
||||
print_if(if_stmt, p, ctx);
|
||||
}
|
||||
_ => {
|
||||
p.print_soft_newline();
|
||||
p.indent();
|
||||
alternate.gen(p, ctx);
|
||||
p.dedent();
|
||||
}
|
||||
stmt => p.print_body(stmt, true, ctx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -296,12 +297,12 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForStatement<'a> {
|
|||
p.print_semicolon();
|
||||
|
||||
if let Some(update) = self.update.as_ref() {
|
||||
p.print_soft_space();
|
||||
p.print_expression(update);
|
||||
}
|
||||
|
||||
p.print(b')');
|
||||
p.print_soft_space();
|
||||
p.print_body(&self.body, ctx);
|
||||
p.print_body(&self.body, false, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -319,8 +320,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForInStatement<'a> {
|
|||
p.print_hard_space();
|
||||
p.print_expression(&self.right);
|
||||
p.print(b')');
|
||||
p.print_soft_space();
|
||||
p.print_body(&self.body, ctx);
|
||||
p.print_body(&self.body, false, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -340,8 +340,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForOfStatement<'a> {
|
|||
p.print_str(b"of ");
|
||||
self.right.gen_expr(p, Precedence::Assign, Context::default());
|
||||
p.print(b')');
|
||||
p.print_soft_space();
|
||||
p.print_body(&self.body, ctx);
|
||||
p.print_body(&self.body, false, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -370,8 +369,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for WhileStatement<'a> {
|
|||
p.print(b'(');
|
||||
p.print_expression(&self.test);
|
||||
p.print(b')');
|
||||
p.print_soft_space();
|
||||
p.print_body(&self.body, ctx);
|
||||
p.print_body(&self.body, false, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -470,12 +468,8 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for SwitchCase<'a> {
|
|||
p.print_colon();
|
||||
|
||||
if self.consequent.len() == 1 {
|
||||
if let Statement::BlockStatement(block) = &self.consequent[0] {
|
||||
p.print_soft_space();
|
||||
p.print_block_statement(block, ctx);
|
||||
p.print_soft_newline();
|
||||
return;
|
||||
}
|
||||
p.print_body(&self.consequent[0], false, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
p.print_soft_newline();
|
||||
|
|
@ -503,12 +497,14 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ReturnStatement<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> Gen<MINIFY> for LabeledStatement<'a> {
|
||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
||||
p.add_source_mapping(self.span.start);
|
||||
p.print_indent();
|
||||
if !MINIFY && (p.indent > 0 || p.print_next_indent_as_space) {
|
||||
p.add_source_mapping(self.span.start);
|
||||
p.print_indent();
|
||||
}
|
||||
p.print_space_before_identifier();
|
||||
self.label.gen(p, ctx);
|
||||
p.print_colon();
|
||||
p.print_soft_space();
|
||||
p.print_body(&self.body, ctx);
|
||||
p.print_body(&self.body, false, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -531,6 +527,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TryStatement<'a> {
|
|||
}
|
||||
p.print_soft_space();
|
||||
p.print_block_statement(&handler.body, ctx);
|
||||
if self.finalizer.is_some() {
|
||||
p.print_soft_newline();
|
||||
}
|
||||
}
|
||||
if let Some(finalizer) = &self.finalizer {
|
||||
p.print_soft_space();
|
||||
|
|
@ -560,7 +559,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for WithStatement<'a> {
|
|||
p.print(b'(');
|
||||
p.print_expression(&self.object);
|
||||
p.print(b')');
|
||||
p.print_body(&self.body, ctx);
|
||||
p.print_body(&self.body, false, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -716,6 +715,10 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
|
|||
}
|
||||
if let Some(specifiers) = &self.specifiers {
|
||||
if specifiers.is_empty() {
|
||||
p.print_str(b"{}");
|
||||
p.print_soft_space();
|
||||
p.print_str(b"from");
|
||||
p.print_soft_space();
|
||||
p.print(b'\'');
|
||||
p.print_str(self.source.value.as_bytes());
|
||||
p.print(b'\'');
|
||||
|
|
@ -732,19 +735,23 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
|
|||
match specifier {
|
||||
ImportDeclarationSpecifier::ImportDefaultSpecifier(spec) => {
|
||||
if in_block {
|
||||
p.print_soft_space();
|
||||
p.print_str(b"},");
|
||||
in_block = false;
|
||||
} else if index != 0 {
|
||||
p.print_comma();
|
||||
p.print_soft_space();
|
||||
}
|
||||
spec.local.gen(p, ctx);
|
||||
}
|
||||
ImportDeclarationSpecifier::ImportNamespaceSpecifier(spec) => {
|
||||
if in_block {
|
||||
p.print_soft_space();
|
||||
p.print_str(b"},");
|
||||
in_block = false;
|
||||
} else if index != 0 {
|
||||
p.print_comma();
|
||||
p.print_soft_space();
|
||||
}
|
||||
p.print_str(b"* as ");
|
||||
spec.local.gen(p, ctx);
|
||||
|
|
@ -752,12 +759,15 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
|
|||
ImportDeclarationSpecifier::ImportSpecifier(spec) => {
|
||||
if in_block {
|
||||
p.print_comma();
|
||||
p.print_soft_space();
|
||||
} else {
|
||||
if index != 0 {
|
||||
p.print_comma();
|
||||
p.print_soft_space();
|
||||
}
|
||||
in_block = true;
|
||||
p.print(b'{');
|
||||
p.print_soft_space();
|
||||
}
|
||||
|
||||
if spec.import_kind.is_type() {
|
||||
|
|
@ -785,6 +795,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
|
|||
}
|
||||
}
|
||||
if in_block {
|
||||
p.print_soft_space();
|
||||
p.print(b'}');
|
||||
}
|
||||
p.print_str(b" from ");
|
||||
|
|
@ -825,6 +836,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportAttribute<'a> {
|
|||
ImportAttributeKey::StringLiteral(literal) => literal.gen(p, ctx),
|
||||
};
|
||||
p.print_colon();
|
||||
p.print_soft_space();
|
||||
self.value.gen(p, ctx);
|
||||
}
|
||||
}
|
||||
|
|
@ -1477,14 +1489,16 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ObjectExpression<'a> {
|
|||
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, _precedence: Precedence, ctx: Context) {
|
||||
let n = p.code_len();
|
||||
p.wrap(p.start_of_stmt == n || p.start_of_arrow_expr == n, |p| {
|
||||
let single_line = self.properties.is_empty();
|
||||
let single_line = self.properties.len() <= 1;
|
||||
p.print_curly_braces(self.span, single_line, |p| {
|
||||
for (index, item) in self.properties.iter().enumerate() {
|
||||
if index != 0 {
|
||||
p.print_comma();
|
||||
p.print_soft_newline();
|
||||
}
|
||||
p.print_indent();
|
||||
if !single_line {
|
||||
p.print_indent();
|
||||
}
|
||||
item.gen(p, ctx);
|
||||
}
|
||||
if !single_line {
|
||||
|
|
@ -1691,9 +1705,10 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for BinaryExpression<'a> {
|
|||
self.left.gen_expr(p, left_precedence, ctx);
|
||||
if self.operator.is_keyword() {
|
||||
p.print_space_before_identifier();
|
||||
} else {
|
||||
p.print_soft_space();
|
||||
}
|
||||
self.operator.gen(p, ctx);
|
||||
p.print_soft_space();
|
||||
let right_precedence = if self.precedence().is_left_associative() {
|
||||
self.precedence()
|
||||
} else {
|
||||
|
|
@ -1714,6 +1729,7 @@ impl<const MINIFY: bool> Gen<MINIFY> for BinaryOperator {
|
|||
let op: Operator = (*self).into();
|
||||
p.print_space_before_operator(op);
|
||||
p.print_str(operator);
|
||||
p.print_soft_space();
|
||||
p.prev_op = Some(op);
|
||||
p.prev_op_end = p.code().len();
|
||||
}
|
||||
|
|
@ -1755,7 +1771,7 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ConditionalExpression<'a> {
|
|||
p.print_soft_space();
|
||||
self.consequent.gen_expr(p, Precedence::Assign, ctx.and_in(true));
|
||||
p.print_soft_space();
|
||||
p.print(b':');
|
||||
p.print_colon();
|
||||
p.print_soft_space();
|
||||
self.alternate.gen_expr(p, Precedence::Assign, ctx.union_in_if(wrap));
|
||||
});
|
||||
|
|
@ -1898,7 +1914,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetMaybeDefault<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetWithDefault<'a> {
|
||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
||||
self.binding.gen(p, ctx);
|
||||
p.print_soft_space();
|
||||
p.print_equal();
|
||||
p.print_soft_space();
|
||||
self.init.gen_expr(p, Precedence::Assign, Context::default());
|
||||
}
|
||||
}
|
||||
|
|
@ -1916,7 +1934,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetPropertyIdentifier<
|
|||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
||||
self.binding.gen(p, ctx);
|
||||
if let Some(expr) = &self.init {
|
||||
p.print_soft_space();
|
||||
p.print_equal();
|
||||
p.print_soft_space();
|
||||
expr.gen_expr(p, Precedence::Assign, Context::default());
|
||||
}
|
||||
}
|
||||
|
|
@ -1938,6 +1958,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetPropertyProperty<'a
|
|||
}
|
||||
}
|
||||
p.print_colon();
|
||||
p.print_soft_space();
|
||||
self.binding.gen(p, ctx);
|
||||
}
|
||||
}
|
||||
|
|
@ -2157,7 +2178,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXElementName<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXNamespacedName<'a> {
|
||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
||||
self.namespace.gen(p, ctx);
|
||||
p.print(b':');
|
||||
p.print_colon();
|
||||
self.property.gen(p, ctx);
|
||||
}
|
||||
}
|
||||
|
|
@ -2175,7 +2196,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXAttribute<'a> {
|
|||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
||||
self.name.gen(p, ctx);
|
||||
if let Some(value) = &self.value {
|
||||
p.print(b'=');
|
||||
p.print_equal();
|
||||
value.gen(p, ctx);
|
||||
}
|
||||
}
|
||||
|
|
@ -2326,6 +2347,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for StaticBlock<'a> {
|
|||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
||||
p.add_source_mapping(self.span.start);
|
||||
p.print_str(b"static");
|
||||
p.print_soft_space();
|
||||
p.print_curly_braces(self.span, self.body.is_empty(), |p| {
|
||||
for stmt in &self.body {
|
||||
p.print_semicolon_if_needed();
|
||||
|
|
@ -2487,6 +2509,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ObjectPattern<'a> {
|
|||
fn gen(&self, p: &mut Codegen<MINIFY>, ctx: Context) {
|
||||
p.add_source_mapping(self.span.start);
|
||||
p.print(b'{');
|
||||
p.print_soft_space();
|
||||
p.print_list(&self.properties, ctx);
|
||||
if let Some(rest) = &self.rest {
|
||||
if !self.properties.is_empty() {
|
||||
|
|
@ -2494,6 +2517,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ObjectPattern<'a> {
|
|||
}
|
||||
rest.gen(p, ctx);
|
||||
}
|
||||
p.print_soft_space();
|
||||
p.print(b'}');
|
||||
p.add_source_mapping(self.span.end);
|
||||
}
|
||||
|
|
@ -2513,6 +2537,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for BindingProperty<'a> {
|
|||
}
|
||||
if !self.shorthand {
|
||||
p.print_colon();
|
||||
p.print_soft_space();
|
||||
}
|
||||
self.value.gen(p, ctx);
|
||||
}
|
||||
|
|
@ -2876,12 +2901,15 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTemplateLiteralType<'a> {
|
|||
|
||||
impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTypeLiteral<'a> {
|
||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
||||
p.print_curly_braces(self.span, self.members.is_empty(), |p| {
|
||||
let single_line = self.members.len() <= 1;
|
||||
p.print_curly_braces(self.span, single_line, |p| {
|
||||
for item in &self.members {
|
||||
p.print_indent();
|
||||
item.gen(p, ctx);
|
||||
p.print_semicolon();
|
||||
p.print_soft_newline();
|
||||
if !single_line {
|
||||
p.print_semicolon();
|
||||
p.print_soft_newline();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ pub struct Codegen<'a, const MINIFY: bool> {
|
|||
prev_op_end: usize,
|
||||
prev_reg_exp_end: usize,
|
||||
need_space_before_dot: usize,
|
||||
print_next_indent_as_space: bool,
|
||||
|
||||
/// For avoiding `;` if the previous statement ends with `}`.
|
||||
needs_semicolon: bool,
|
||||
|
|
@ -95,7 +96,7 @@ pub struct Codegen<'a, const MINIFY: bool> {
|
|||
start_of_default_export: usize,
|
||||
|
||||
/// Track the current indentation level
|
||||
indentation: u8,
|
||||
indent: u8,
|
||||
|
||||
// Builders
|
||||
sourcemap_builder: Option<SourcemapBuilder>,
|
||||
|
|
@ -139,13 +140,14 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
code: Vec::with_capacity(capacity),
|
||||
needs_semicolon: false,
|
||||
need_space_before_dot: 0,
|
||||
print_next_indent_as_space: false,
|
||||
prev_op_end: 0,
|
||||
prev_reg_exp_end: 0,
|
||||
prev_op: None,
|
||||
start_of_stmt: 0,
|
||||
start_of_arrow_expr: 0,
|
||||
start_of_default_export: 0,
|
||||
indentation: 0,
|
||||
indent: 0,
|
||||
sourcemap_builder,
|
||||
move_comment_map: MoveCommentMap::default(),
|
||||
}
|
||||
|
|
@ -224,30 +226,36 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
self.move_comment_map.get(&start)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_soft_space(&mut self) {
|
||||
if !MINIFY {
|
||||
self.print(b' ');
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn print_hard_space(&mut self) {
|
||||
self.print(b' ');
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_soft_newline(&mut self) {
|
||||
if !MINIFY {
|
||||
self.print(b'\n');
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_semicolon(&mut self) {
|
||||
self.print(b';');
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_comma(&mut self) {
|
||||
self.print(b',');
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_space_before_identifier(&mut self) {
|
||||
if self
|
||||
.peek_nth(0)
|
||||
|
|
@ -257,32 +265,41 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn peek_nth(&self, n: usize) -> Option<char> {
|
||||
#[allow(unsafe_code)]
|
||||
// SAFETY: criteria of `from_utf8_unchecked` are met.
|
||||
unsafe { std::str::from_utf8_unchecked(self.code()) }.chars().nth_back(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn indent(&mut self) {
|
||||
if !MINIFY {
|
||||
self.indentation += 1;
|
||||
self.indent += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn dedent(&mut self) {
|
||||
if !MINIFY {
|
||||
self.indentation -= 1;
|
||||
self.indent -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_indent(&mut self) {
|
||||
if !MINIFY {
|
||||
for _ in 0..self.indentation {
|
||||
self.print(b'\t');
|
||||
}
|
||||
if MINIFY {
|
||||
return;
|
||||
}
|
||||
if self.print_next_indent_as_space {
|
||||
self.print_hard_space();
|
||||
self.print_next_indent_as_space = false;
|
||||
return;
|
||||
}
|
||||
self.code.extend(std::iter::repeat(b'\t').take(self.indent as usize));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_semicolon_after_statement(&mut self) {
|
||||
if MINIFY {
|
||||
self.needs_semicolon = true;
|
||||
|
|
@ -291,6 +308,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_semicolon_if_needed(&mut self) {
|
||||
if self.needs_semicolon {
|
||||
self.print_semicolon();
|
||||
|
|
@ -298,14 +316,17 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_ellipsis(&mut self) {
|
||||
self.print_str(b"...");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn print_colon(&mut self) {
|
||||
self.print(b':');
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_equal(&mut self) {
|
||||
self.print(b'=');
|
||||
}
|
||||
|
|
@ -351,13 +372,24 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
self.print(b'}');
|
||||
}
|
||||
|
||||
fn print_body(&mut self, stmt: &Statement<'_>, ctx: Context) {
|
||||
fn print_body(&mut self, stmt: &Statement<'_>, need_space: bool, ctx: Context) {
|
||||
match stmt {
|
||||
Statement::BlockStatement(stmt) => {
|
||||
self.print_soft_space();
|
||||
self.print_block_statement(stmt, ctx);
|
||||
self.print_soft_newline();
|
||||
}
|
||||
stmt => stmt.gen(self, ctx),
|
||||
Statement::EmptyStatement(_) => {
|
||||
self.print_semicolon();
|
||||
self.print_soft_newline();
|
||||
}
|
||||
stmt => {
|
||||
if need_space && MINIFY {
|
||||
self.print_hard_space();
|
||||
}
|
||||
self.print_next_indent_as_space = true;
|
||||
stmt.gen(self, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -390,6 +422,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn print_expression(&mut self, expr: &Expression<'_>) {
|
||||
expr.gen_expr(self, Precedence::lowest(), Context::default());
|
||||
}
|
||||
|
|
@ -422,10 +455,6 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
}
|
||||
|
||||
fn print_space_before_operator(&mut self, next: Operator) {
|
||||
if !MINIFY {
|
||||
self.print_hard_space();
|
||||
return;
|
||||
}
|
||||
if self.prev_op_end != self.code.len() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -457,6 +486,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn wrap<F: FnMut(&mut Self)>(&mut self, wrap: bool, mut f: F) {
|
||||
if wrap {
|
||||
self.print(b'(');
|
||||
|
|
@ -467,6 +497,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn wrap_quote<F: FnMut(&mut Self, char)>(&mut self, s: &str, mut f: F) {
|
||||
let quote = choose_quote(s);
|
||||
self.print(quote as u8);
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ fn template() {
|
|||
fn module_decl() {
|
||||
test("export * as foo from 'foo'", "export * as foo from 'foo';\n", None);
|
||||
test("import x from './foo.js' with {}", "import x from './foo.js' with {\n};\n", None);
|
||||
test("import {} from './foo.js' with {}", "import './foo.js' with {\n};\n", None);
|
||||
test("import {} from './foo.js' with {}", "import {} from './foo.js' with {\n};\n", None);
|
||||
test("export * from './foo.js' with {}", "export * from './foo.js' with {\n};\n", None);
|
||||
}
|
||||
|
||||
|
|
@ -176,8 +176,12 @@ fn typescript() {
|
|||
test_ts("function isString(value: unknown): asserts value is string {\n\tif (typeof value !== 'string') {\n\t\tthrow new Error('Not a string');\n\t}\n}", "function isString(value: unknown): asserts value is string {\n\tif (typeof value !== 'string') {\n\t\tthrow new Error('Not a string');\n\t}\n}\n", false);
|
||||
|
||||
// type-only imports/exports
|
||||
test_ts("import type { Foo } from 'foo';", "import type {Foo} from 'foo';\n", false);
|
||||
test_ts("import { Foo, type Bar } from 'foo';", "import {Foo,type Bar} from 'foo';\n", false);
|
||||
test_ts("import type { Foo } from 'foo';", "import type { Foo } from 'foo';\n", false);
|
||||
test_ts(
|
||||
"import { Foo, type Bar } from 'foo';",
|
||||
"import { Foo, type Bar } from 'foo';\n",
|
||||
false,
|
||||
);
|
||||
test_ts(
|
||||
"export { Foo, type Bar } from 'foo';",
|
||||
"export { Foo, type Bar } from 'foo';\n",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -17,61 +17,49 @@ Mismatch: "declarationSingleFileHasErrorsReported.ts"
|
|||
|
||||
#### "declarationLinkedAliases.ts" ####
|
||||
//// [declarationLinkedAliases.ts] ////
|
||||
import {A} from 'mod';
|
||||
import { A } from 'mod';
|
||||
import B = A.C;
|
||||
export { B };
|
||||
|
||||
//// [declarationLinkedAliases.d.ts] ////
|
||||
import {A} from 'mod';
|
||||
import { A } from 'mod';
|
||||
import B = A.C;
|
||||
export { B };
|
||||
|
||||
#### "declarationLocalAliasOfImportAlias.ts" ####
|
||||
//// [declarationLocalAliasOfImportAlias.ts] ////
|
||||
import {Record} from './a';
|
||||
import { Record } from './a';
|
||||
export type Foo<K extends string> = Record<K, number>;
|
||||
export const obj = {
|
||||
doThing<K extends string>(_k: K) {
|
||||
return ({} as any);
|
||||
}
|
||||
};
|
||||
export const obj = {doThing<K extends string>(_k: K) {
|
||||
return ({} as any);
|
||||
}};
|
||||
|
||||
//// [declarationLocalAliasOfImportAlias.d.ts] ////
|
||||
import {Record} from './a';
|
||||
import { Record } from './a';
|
||||
export type Foo<K extends string> = Record<K, number>;
|
||||
export declare const obj: {
|
||||
doThing<K extends string>(_k: K): Foo<K>;
|
||||
};
|
||||
export declare const obj: {doThing<K extends string>(_k: K): Foo<K>};
|
||||
|
||||
#### "declarationSelfReferentialConstraint.ts" ####
|
||||
//// [declarationSelfReferentialConstraint.ts] ////
|
||||
export const object = {
|
||||
foo: <T extends ((Set<T>) | ([]))>(): void => {}
|
||||
};
|
||||
export const object = {foo: <T extends ((Set<T>) | ([]))>(): void => {}};
|
||||
|
||||
//// [declarationSelfReferentialConstraint.d.ts] ////
|
||||
export declare const object: {
|
||||
foo: <T extends ((Set<T>) | ([]))>() => void;
|
||||
};
|
||||
export declare const object: {foo: <T extends ((Set<T>) | ([]))>() => void};
|
||||
|
||||
#### "declarationTypeParameterConstraint.ts" ####
|
||||
//// [declarationTypeParameterConstraint.ts] ////
|
||||
import {type In,type Out,type Base} from './a';
|
||||
export const object = {
|
||||
doThing<T extends Base>(_t: T, _in: In[T]) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
import { type In, type Out, type Base } from './a';
|
||||
export const object = {doThing<T extends Base>(_t: T, _in: In[T]) {
|
||||
return;
|
||||
}};
|
||||
|
||||
//// [declarationTypeParameterConstraint.d.ts] ////
|
||||
import {type In,type Out,type Base} from './a';
|
||||
export declare const object: {
|
||||
doThing<T extends Base>(_t: T, _in: In[T]): Out[T];
|
||||
};
|
||||
import { type In, type Out, type Base } from './a';
|
||||
export declare const object: {doThing<T extends Base>(_t: T, _in: In[T]): Out[T]};
|
||||
|
||||
#### "declarationTypeWithComputedName.ts" ####
|
||||
//// [declarationTypeWithComputedName.ts] ////
|
||||
import {Foo} from './a';
|
||||
import { Foo } from './a';
|
||||
export type Bar = {
|
||||
[Foo.A]: 1;
|
||||
[Foo.B]: 2;
|
||||
|
|
@ -82,7 +70,7 @@ export const valBar = ((null as any) as {
|
|||
});
|
||||
|
||||
//// [declarationTypeWithComputedName.d.ts] ////
|
||||
import {Foo} from './a';
|
||||
import { Foo } from './a';
|
||||
export type Bar = {
|
||||
[Foo.A]: 1;
|
||||
[Foo.B]: 2;
|
||||
|
|
@ -100,9 +88,7 @@ export const fn2 = (a: MissingGlobalType) => (null as MissingGlobalType);
|
|||
export const x2: typeof missingGlobalValue = null;
|
||||
export const fn3 = (a: typeof missingGlobalValue): typeof missingGlobalValue => null;
|
||||
export const fn4 = (a: typeof missingGlobalValue) => (null as typeof missingGlobalValue);
|
||||
export const o: {
|
||||
[missingGlobalValue]: string;
|
||||
} = null;
|
||||
export const o: {[missingGlobalValue]: string} = null;
|
||||
|
||||
//// [declarationUnresolvedGlobalReferencesNoErrors.d.ts] ////
|
||||
export declare const x: MissingGlobalType;
|
||||
|
|
@ -111,18 +97,16 @@ export declare const fn2: (a: MissingGlobalType) => MissingGlobalType;
|
|||
export declare const x2: typeof missingGlobalValue;
|
||||
export declare const fn3: (a: typeof missingGlobalValue) => typeof missingGlobalValue;
|
||||
export declare const fn4: (a: typeof missingGlobalValue) => typeof missingGlobalValue;
|
||||
export declare const o: {
|
||||
[missingGlobalValue]: string;
|
||||
};
|
||||
export declare const o: {[missingGlobalValue]: string};
|
||||
|
||||
#### "declarationUnresolvedTypeReference.ts" ####
|
||||
//// [declarationUnresolvedTypeReference.ts] ////
|
||||
import {type Type} from './a';
|
||||
import { type Type } from './a';
|
||||
export const foo = (_: Type): void => {};
|
||||
export const bar = (_: import('./a').Type): void => {};
|
||||
|
||||
//// [declarationUnresolvedTypeReference.d.ts] ////
|
||||
import {type Type} from './a';
|
||||
import { type Type } from './a';
|
||||
export declare const foo: (_: Type) => void;
|
||||
export declare const bar: (_: import('./a').Type) => void;
|
||||
|
||||
|
|
@ -153,12 +137,8 @@ export const c: number = 1;
|
|||
export interface A {
|
||||
x: number;
|
||||
}
|
||||
let expr: {
|
||||
x: number;
|
||||
};
|
||||
expr = {
|
||||
x: 12
|
||||
};
|
||||
let expr: {x: number};
|
||||
expr = {x: 12};
|
||||
export default expr;
|
||||
|
||||
//// [declarationsSimple.d.ts] ////
|
||||
|
|
@ -166,7 +146,5 @@ export declare const c: number;
|
|||
export interface A {
|
||||
x: number;
|
||||
}
|
||||
declare let expr: {
|
||||
x: number;
|
||||
};
|
||||
declare let expr: {x: number};
|
||||
export default expr;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
commit: 12619ffe
|
||||
|
||||
Passed: 478/927
|
||||
Passed: 474/927
|
||||
|
||||
# All Passed:
|
||||
* babel-preset-react
|
||||
|
|
@ -445,12 +445,16 @@ Passed: 478/927
|
|||
* opts/optimizeConstEnums/input.ts
|
||||
* opts/rewriteImportExtensions/input.ts
|
||||
|
||||
# babel-plugin-transform-typescript (134/151)
|
||||
# babel-plugin-transform-typescript (130/151)
|
||||
* enum/mix-references/input.ts
|
||||
* enum/ts5.0-const-foldable/input.ts
|
||||
* exports/declared-types/input.ts
|
||||
* exports/interface/input.ts
|
||||
* imports/elide-no-import-specifiers/input.ts
|
||||
* imports/import-removed-exceptions/input.ts
|
||||
* imports/only-remove-type-imports/input.ts
|
||||
* imports/type-only-export-specifier-2/input.ts
|
||||
* imports/type-only-import-specifier-4/input.ts
|
||||
* optimize-const-enums/custom-values/input.ts
|
||||
* optimize-const-enums/custom-values-exported/input.ts
|
||||
* optimize-const-enums/declare/input.ts
|
||||
|
|
|
|||
Loading…
Reference in a new issue