feat(codegen): beauty class print (#995)

This commit is contained in:
Wenzhe Wang 2023-10-15 03:37:01 -05:00 committed by GitHub
parent 47872200e5
commit 6c18b3e8ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 12 deletions

View file

@ -1055,7 +1055,7 @@ impl<'a> Declaration<'a> {
match self {
Self::VariableDeclaration(decl) => decl.is_typescript_syntax(),
Self::FunctionDeclaration(func) => func.is_typescript_syntax(),
Self::ClassDeclaration(class) => class.is_declare(),
Self::ClassDeclaration(class) => class.is_typescript_syntax(),
_ => true,
}
}
@ -1633,6 +1633,10 @@ impl<'a> Class<'a> {
pub fn is_declare(&self) -> bool {
self.modifiers.contains(ModifierKind::Declare)
}
pub fn is_typescript_syntax(&self) -> bool {
self.is_declare()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -1730,6 +1734,17 @@ impl<'a> ClassElement<'a> {
Self::TSAbstractMethodDefinition(_) => true,
}
}
pub fn is_typescript_syntax(&self) -> bool {
match self {
Self::TSIndexSignature(_)
| Self::TSAbstractMethodDefinition(_)
| Self::TSAbstractPropertyDefinition(_) => true,
Self::MethodDefinition(method) => method.value.is_typescript_syntax(),
Self::PropertyDefinition(property) => property.declare,
_ => false,
}
}
}
#[derive(Debug, Hash)]
@ -2004,6 +2019,11 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
{
true
}
ExportDefaultDeclarationKind::ClassDeclaration(class)
if class.is_typescript_syntax() =>
{
true
}
ExportDefaultDeclarationKind::TSInterfaceDeclaration(_)
| ExportDefaultDeclarationKind::TSEnumDeclaration(_) => true,
_ => false,

View file

@ -10,7 +10,7 @@ use oxc_span::SourceType;
// 2. run `cargo run -p oxc_codegen --example codegen` or `just example codegen`
fn main() {
let name = env::args().nth(1).unwrap_or_else(|| "test.tsx".to_string());
let name = env::args().nth(1).unwrap_or_else(|| "test.js".to_string());
let path = Path::new(&name);
let source_text = std::fs::read_to_string(path).unwrap_or_else(|_| panic!("{name} not found"));
let source_type = SourceType::from_path(path).unwrap();
@ -29,7 +29,7 @@ fn main() {
println!("{source_text}");
let codegen_options = CodegenOptions;
let printed = Codegen::<true>::new(source_text.len(), codegen_options).build(&ret.program);
let printed = Codegen::<false>::new(source_text.len(), codegen_options).build(&ret.program);
println!("Printed:");
println!("{printed}");

View file

@ -491,6 +491,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for Declaration<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
match self {
Self::VariableDeclaration(decl) => {
// Codegen is not intended to be used as a code formatting tool, so we need filter out the TypeScript syntax here.
if !decl.is_typescript_syntax() {
p.print_indent();
decl.gen(p, ctx);
@ -505,8 +506,11 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for Declaration<'a> {
}
}
Self::ClassDeclaration(decl) => {
p.print_space_before_identifier();
decl.gen(p, ctx);
if !decl.is_typescript_syntax() {
p.print_space_before_identifier();
decl.gen(p, ctx);
p.print_soft_newline();
}
}
Self::UsingDeclaration(declaration) => {
p.print_space_before_identifier();
@ -796,7 +800,12 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ExportDefaultDeclarationKind<'a> {
p.print_semicolon_after_statement();
}
Self::FunctionDeclaration(fun) => fun.gen(p, ctx),
Self::ClassDeclaration(value) => value.gen(p, ctx),
Self::ClassDeclaration(class) => {
if !class.is_typescript_syntax() {
class.gen(p, ctx);
p.print_soft_newline();
}
}
_ => {}
}
}
@ -1658,6 +1667,10 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for Class<'a> {
p.print_soft_space();
p.print_block_start();
for item in &self.body.body {
if item.is_typescript_syntax() {
continue;
}
p.print_indent();
p.print_semicolon_if_needed();
item.gen(p, ctx);
if matches!(
@ -1666,9 +1679,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for Class<'a> {
) {
p.print_semicolon_after_statement();
}
p.print_soft_newline();
}
p.print_block_end();
p.print_soft_newline();
p.needs_semicolon = false;
});
}

View file

@ -1,6 +1,6 @@
codegen_typescript Summary:
AST Parsed : 5063/5063 (100.00%)
Positive Passed: 4968/5063 (98.12%)
Positive Passed: 4972/5063 (98.20%)
Expect to Parse: "compiler/binopAssignmentShouldHaveType.ts"
Expect to Parse: "compiler/callOfConditionalTypeWithConcreteBranches.ts"
Expect to Parse: "compiler/castExpressionParentheses.ts"
@ -13,7 +13,6 @@ Expect to Parse: "compiler/declarationEmitDestructuringObjectLiteralPattern2.ts"
Expect to Parse: "compiler/declarationEmitNonExportedBindingPattern.ts"
Expect to Parse: "compiler/declarationEmitRetainsJsdocyComments.ts"
Expect to Parse: "compiler/declarationMaps.ts"
Expect to Parse: "compiler/declarationTypecheckNoUseBeforeReferenceCheck.ts"
Expect to Parse: "compiler/declareFileExportAssignment.ts"
Expect to Parse: "compiler/declareFileExportAssignmentWithVarFromVariableStatement.ts"
Expect to Parse: "compiler/doNotEmitPinnedCommentOnNotEmittedNode.ts"
@ -38,7 +37,6 @@ Expect to Parse: "compiler/exportEqualNamespaces.ts"
Expect to Parse: "compiler/genericOverloadSignatures.ts"
Expect to Parse: "compiler/identityRelationNeverTypes.ts"
Expect to Parse: "compiler/indexingTypesWithNever.ts"
Expect to Parse: "compiler/inferenceErasedSignatures.ts"
Expect to Parse: "compiler/interfaceWithCommaSeparators.ts"
Expect to Parse: "compiler/jsxMultilineAttributeStringValues.tsx"
Expect to Parse: "compiler/jsxMultilineAttributeValuesReact.tsx"
@ -48,7 +46,6 @@ Expect to Parse: "compiler/localClassesInLoop.ts"
Expect to Parse: "compiler/localClassesInLoop_ES6.ts"
Expect to Parse: "compiler/moduleVariables.ts"
Expect to Parse: "compiler/module_augmentUninstantiatedModule2.ts"
Expect to Parse: "compiler/numericIndexerConstraint3.ts"
Expect to Parse: "compiler/objectAssignLikeNonUnionResult.ts"
Expect to Parse: "compiler/privacyCheckAnonymousFunctionParameter.ts"
Expect to Parse: "compiler/privacyCheckAnonymousFunctionParameter2.ts"
@ -87,7 +84,6 @@ Expect to Parse: "conformance/jsx/jsxReactTestSuite.tsx"
Expect to Parse: "conformance/jsx/tsxNamespacedAttributeName1.tsx"
Expect to Parse: "conformance/jsx/tsxNamespacedAttributeName2.tsx"
Expect to Parse: "conformance/jsx/tsxReactEmitEntities.tsx"
Expect to Parse: "conformance/types/namedTypes/optionalMethods.ts"
Expect to Parse: "conformance/types/rest/genericRestParameters2.ts"
Expect to Parse: "conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts"
Expect to Parse: "conformance/types/stringLiteral/stringLiteralTypesOverloads02.ts"