support class literals (#4658)

This commit is contained in:
Alex Lam S.L
2021-02-23 14:55:08 +00:00
committed by GitHub
parent e535f19189
commit d68d155f93
18 changed files with 1701 additions and 175 deletions

View File

@@ -671,6 +671,7 @@ function OutputStream(options) {
}
PARENS(AST_AsyncFunction, needs_parens_function);
PARENS(AST_AsyncGeneratorFunction, needs_parens_function);
PARENS(AST_ClassExpression, needs_parens_function);
PARENS(AST_Function, needs_parens_function);
PARENS(AST_GeneratorFunction, needs_parens_function);
@@ -688,6 +689,9 @@ function OutputStream(options) {
// (await x)(y)
// new (await x)
if (p instanceof AST_Call) return p.expression === this;
// class extends (x++) {}
// class x extends (typeof y) {}
if (p instanceof AST_Class) return true;
// (x++)[y]
// (typeof x).y
if (p instanceof AST_PropAccess) return p.expression === this;
@@ -707,6 +711,12 @@ function OutputStream(options) {
|| p instanceof AST_Binary
// new (foo, bar) or foo(1, (2, 3), 4)
|| p instanceof AST_Call
// class extends (foo, bar) {}
// class foo extends (bar, baz) {}
|| p instanceof AST_Class
// class { foo = (bar, baz) }
// class { [(foo, bar)]() {} }
|| p instanceof AST_ClassProperty
// (false, true) ? (a = 10, b = 20) : (c = 30)
// ---> 20 (side effect, set a := 10 and b := 20)
|| p instanceof AST_Conditional
@@ -747,6 +757,9 @@ function OutputStream(options) {
}
// (foo && bar)()
if (p instanceof AST_Call) return p.expression === this;
// class extends (foo && bar) {}
// class foo extends (bar || null) {}
if (p instanceof AST_Class) return true;
// (foo && bar)["prop"], (foo && bar).prop
if (p instanceof AST_PropAccess) return p.expression === this;
// typeof (foo && bar)
@@ -810,6 +823,9 @@ function OutputStream(options) {
if (p instanceof AST_Binary) return !(p instanceof AST_Assign);
// (a = func)() —or— new (a = Object)()
if (p instanceof AST_Call) return p.expression === self;
// class extends (a = foo) {}
// class foo extends (bar ? baz : moo) {}
if (p instanceof AST_Class) return true;
// (a = foo) ? bar : baz
if (p instanceof AST_Conditional) return p.condition === self;
// (a = foo)["prop"] —or— (a = foo).prop
@@ -1015,7 +1031,9 @@ function OutputStream(options) {
output.print("default");
output.space();
this.body.print(output);
if (!(this.body instanceof AST_Lambda) || is_arrow(this.body)) output.semicolon();
if (this.body instanceof AST_Class) return;
if (this.body instanceof AST_Lambda && !is_arrow(this.body)) return;
output.semicolon();
});
DEFPRINT(AST_ExportForeign, function(output) {
var self = this;
@@ -1157,6 +1175,59 @@ function OutputStream(options) {
DEFPRINT(AST_GeneratorDefun, print_generator);
DEFPRINT(AST_GeneratorFunction, print_generator);
/* -----[ classes ]----- */
DEFPRINT(AST_Class, function(output) {
var self = this;
output.print("class");
if (self.name) {
output.space();
self.name.print(output);
}
if (self.extends) {
output.space();
output.print("extends");
output.space();
self.extends.print(output);
}
output.space();
print_properties(self, output, true);
});
DEFPRINT(AST_ClassField, function(output) {
var self = this;
if (self.static) {
output.print("static");
output.space();
}
print_property_key(self, output);
if (self.value) {
output.space();
output.print("=");
output.space();
self.value.print(output);
}
output.semicolon();
});
DEFPRINT(AST_ClassGetter, print_accessor("get"));
DEFPRINT(AST_ClassSetter, print_accessor("set"));
function print_method(self, output) {
var fn = self.value;
if (is_async(fn)) {
output.print("async");
output.space();
}
if (is_generator(fn)) output.print("*");
print_property_key(self, output);
print_lambda(self.value, output);
}
DEFPRINT(AST_ClassMethod, function(output) {
var self = this;
if (self.static) {
output.print("static");
output.space();
}
print_method(self, output);
});
/* -----[ jumps ]----- */
function print_jump(kind, prop) {
return function(output) {
@@ -1526,12 +1597,12 @@ function OutputStream(options) {
});
else print_braced_empty(this, output);
});
function print_properties(self, output) {
function print_properties(self, output, no_comma) {
var props = self.properties;
if (props.length > 0) output.with_block(function() {
props.forEach(function(prop, i) {
if (i) {
output.print(",");
if (!no_comma) output.print(",");
output.newline();
}
output.indent();
@@ -1557,7 +1628,9 @@ function OutputStream(options) {
output.print(make_num(key));
} else {
var quote = self.start && self.start.quote;
if (RESERVED_WORDS[key] ? !output.option("ie8") : is_identifier_string(key)) {
if (self.private) {
output.print_name(key);
} else if (RESERVED_WORDS[key] ? !output.option("ie8") : is_identifier_string(key)) {
if (quote && output.option("keep_quoted_props")) {
output.print_string(key, quote);
} else {
@@ -1576,9 +1649,16 @@ function OutputStream(options) {
self.value.print(output);
}
DEFPRINT(AST_ObjectKeyVal, print_key_value);
DEFPRINT(AST_ObjectMethod, function(output) {
print_method(this, output);
});
function print_accessor(type) {
return function(output) {
var self = this;
if (self.static) {
output.print("static");
output.space();
}
output.print(type);
output.space();
print_property_key(self, output);
@@ -1615,9 +1695,6 @@ function OutputStream(options) {
print_symbol(self, output);
});
DEFPRINT(AST_Hole, noop);
DEFPRINT(AST_This, function(output) {
output.print("this");
});
DEFPRINT(AST_Template, function(output) {
var self = this;
if (self.tag) self.tag.print(output);