Merge pull request #870 from fabiosantoscode/feature/harmony-class
Harmony: classes
This commit is contained in:
57
lib/ast.js
57
lib/ast.js
@@ -473,7 +473,10 @@ var AST_Arrow = DEFNODE("Arrow", null, {
|
|||||||
$documentation: "An ES6 Arrow function ((a) => b)"
|
$documentation: "An ES6 Arrow function ((a) => b)"
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_ConciseMethod = DEFNODE("ConciseMethod", null, {
|
var AST_ConciseMethod = DEFNODE("ConciseMethod", "static", {
|
||||||
|
$propdoc: {
|
||||||
|
static: "[boolean] whether this method is static (classes only)",
|
||||||
|
},
|
||||||
$documentation: "An ES6 concise method inside an object or class"
|
$documentation: "An ES6 concise method inside an object or class"
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
@@ -947,14 +950,50 @@ var AST_ObjectSymbol = DEFNODE("ObjectSymbol", "symbol", {
|
|||||||
}
|
}
|
||||||
}, AST_ObjectProperty);
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
var AST_ObjectSetter = DEFNODE("ObjectSetter", null, {
|
var AST_ObjectSetter = DEFNODE("ObjectSetter", "static", {
|
||||||
|
$propdoc: {
|
||||||
|
static: "[boolean] whether this is a static setter (classes only)"
|
||||||
|
},
|
||||||
$documentation: "An object setter property",
|
$documentation: "An object setter property",
|
||||||
}, AST_ObjectProperty);
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
var AST_ObjectGetter = DEFNODE("ObjectGetter", null, {
|
var AST_ObjectGetter = DEFNODE("ObjectGetter", "static", {
|
||||||
|
$propdoc: {
|
||||||
|
static: "[boolean] whether this is a static getter (classes only)"
|
||||||
|
},
|
||||||
$documentation: "An object getter property",
|
$documentation: "An object getter property",
|
||||||
}, AST_ObjectProperty);
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
|
var AST_Class = DEFNODE("Class", "name extends properties", {
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolClass|AST_SymbolDefClass?] optional class name.",
|
||||||
|
extends: "[AST_Node]? optional parent class",
|
||||||
|
properties: "[AST_ObjectProperty*] array of properties"
|
||||||
|
},
|
||||||
|
$documentation: "An ES6 class",
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
if (this.name) {
|
||||||
|
this.name._walk(visitor);
|
||||||
|
}
|
||||||
|
if (this.extends) {
|
||||||
|
this.extends._walk(visitor);
|
||||||
|
}
|
||||||
|
this.properties.forEach(function(prop){
|
||||||
|
prop._walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}, AST_Scope);
|
||||||
|
|
||||||
|
var AST_DefClass = DEFNODE("DefClass", null, {
|
||||||
|
$documentation: "A class definition",
|
||||||
|
}, AST_Class);
|
||||||
|
|
||||||
|
var AST_ClassExpression = DEFNODE("ClassExpression", null, {
|
||||||
|
$documentation: "A class expression."
|
||||||
|
}, AST_Class);
|
||||||
|
|
||||||
var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
name: "[string] name of this symbol",
|
name: "[string] name of this symbol",
|
||||||
@@ -964,6 +1003,10 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
|||||||
$documentation: "Base class for all symbols",
|
$documentation: "Base class for all symbols",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var AST_NewTarget = DEFNODE("NewTarget", null, {
|
||||||
|
$documentation: "A reference to new.target"
|
||||||
|
});
|
||||||
|
|
||||||
var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
||||||
$documentation: "The name of a property accessor (setter/getter function)"
|
$documentation: "The name of a property accessor (setter/getter function)"
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
@@ -999,6 +1042,14 @@ var AST_SymbolLambda = DEFNODE("SymbolLambda", null, {
|
|||||||
$documentation: "Symbol naming a function expression",
|
$documentation: "Symbol naming a function expression",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, {
|
||||||
|
$documentation: "Symbol naming a class's name in a class declaration. Lexically scoped to its containing scope, and accessible within the class."
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolClass = DEFNODE("SymbolClass", null, {
|
||||||
|
$documentation: "Symbol naming a class's name. Lexically scoped to the class."
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
||||||
$documentation: "Symbol naming the exception in catch",
|
$documentation: "Symbol naming the exception in catch",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|||||||
@@ -769,9 +769,11 @@ function OutputStream(options) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
if (!nokeyword) {
|
if (!nokeyword) {
|
||||||
output.print("function");
|
output.print("function");
|
||||||
|
if (self.name) {
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (self.name) {
|
if (self.name) {
|
||||||
output.space();
|
|
||||||
self.name.print(output);
|
self.name.print(output);
|
||||||
}
|
}
|
||||||
output.with_parens(function(){
|
output.with_parens(function(){
|
||||||
@@ -833,6 +835,10 @@ function OutputStream(options) {
|
|||||||
if (needs_parens) { output.print(")") }
|
if (needs_parens) { output.print(")") }
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ConciseMethod, function(self, output){
|
DEFPRINT(AST_ConciseMethod, function(self, output){
|
||||||
|
if (self.static) {
|
||||||
|
output.print("static");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
self._do_print(output, true /* do not print "function" */);
|
self._do_print(output, true /* do not print "function" */);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1188,6 +1194,34 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
else output.print("{}");
|
else output.print("{}");
|
||||||
});
|
});
|
||||||
|
DEFPRINT(AST_Class, function(self, output){
|
||||||
|
output.print("class");
|
||||||
|
output.space();
|
||||||
|
if (self.name) {
|
||||||
|
self.name.print(output);
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
if (self.extends) {
|
||||||
|
output.print("extends");
|
||||||
|
output.space();
|
||||||
|
self.extends.print(output);
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
if (self.properties.length > 0) output.with_block(function(){
|
||||||
|
self.properties.forEach(function(prop, i){
|
||||||
|
if (i) {
|
||||||
|
output.newline();
|
||||||
|
}
|
||||||
|
output.indent();
|
||||||
|
prop.print(output);
|
||||||
|
});
|
||||||
|
output.newline();
|
||||||
|
});
|
||||||
|
else output.print("{}");
|
||||||
|
});
|
||||||
|
DEFPRINT(AST_NewTarget, function(self, output) {
|
||||||
|
output.print("new.target");
|
||||||
|
});
|
||||||
DEFPRINT(AST_ObjectKeyVal, function(self, output){
|
DEFPRINT(AST_ObjectKeyVal, function(self, output){
|
||||||
var key = self.key;
|
var key = self.key;
|
||||||
var quote = self.quote;
|
var quote = self.quote;
|
||||||
@@ -1207,12 +1241,20 @@ function OutputStream(options) {
|
|||||||
self.value.print(output);
|
self.value.print(output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ObjectSetter, function(self, output){
|
DEFPRINT(AST_ObjectSetter, function(self, output){
|
||||||
|
if (self.static) {
|
||||||
|
output.print("static");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
output.print("set");
|
output.print("set");
|
||||||
output.space();
|
output.space();
|
||||||
self.key.print(output);
|
self.key.print(output);
|
||||||
self.value._do_print(output, true);
|
self.value._do_print(output, true);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ObjectGetter, function(self, output){
|
DEFPRINT(AST_ObjectGetter, function(self, output){
|
||||||
|
if (self.static) {
|
||||||
|
output.print("static");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
output.print("get");
|
output.print("get");
|
||||||
output.space();
|
output.space();
|
||||||
self.key.print(output);
|
self.key.print(output);
|
||||||
|
|||||||
127
lib/parse.js
127
lib/parse.js
@@ -44,9 +44,9 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var let void while with';
|
var KEYWORDS = 'break case catch class const continue debugger default delete do else extends finally for function if in instanceof new return switch throw try typeof var let void while with';
|
||||||
var KEYWORDS_ATOM = 'false null true';
|
var KEYWORDS_ATOM = 'false null true';
|
||||||
var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield'
|
var RESERVED_WORDS = 'abstract boolean byte char double enum export final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield'
|
||||||
+ " " + KEYWORDS_ATOM + " " + KEYWORDS;
|
+ " " + KEYWORDS_ATOM + " " + KEYWORDS;
|
||||||
var KEYWORDS_BEFORE_EXPRESSION = 'return new delete throw else case';
|
var KEYWORDS_BEFORE_EXPRESSION = 'return new delete throw else case';
|
||||||
|
|
||||||
@@ -855,6 +855,9 @@ function parse($TEXT, options) {
|
|||||||
case "for":
|
case "for":
|
||||||
return for_();
|
return for_();
|
||||||
|
|
||||||
|
case "class":
|
||||||
|
return class_(AST_DefClass);
|
||||||
|
|
||||||
case "function":
|
case "function":
|
||||||
return function_(AST_Defun);
|
return function_(AST_Defun);
|
||||||
|
|
||||||
@@ -1289,6 +1292,14 @@ function parse($TEXT, options) {
|
|||||||
var new_ = function(allow_calls) {
|
var new_ = function(allow_calls) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
expect_token("operator", "new");
|
expect_token("operator", "new");
|
||||||
|
if (is("punc", ".")) {
|
||||||
|
next();
|
||||||
|
expect_token("name");
|
||||||
|
return subscripts(new AST_NewTarget({
|
||||||
|
start : start,
|
||||||
|
end : prev()
|
||||||
|
}), allow_calls);
|
||||||
|
}
|
||||||
var newexp = expr_atom(false), args;
|
var newexp = expr_atom(false), args;
|
||||||
if (is("punc", "(")) {
|
if (is("punc", "(")) {
|
||||||
next();
|
next();
|
||||||
@@ -1374,6 +1385,13 @@ function parse($TEXT, options) {
|
|||||||
func.end = prev();
|
func.end = prev();
|
||||||
return subscripts(func, allow_calls);
|
return subscripts(func, allow_calls);
|
||||||
}
|
}
|
||||||
|
if (is("keyword", "class")) {
|
||||||
|
next();
|
||||||
|
var cls = class_(AST_ClassExpression);
|
||||||
|
cls.start = start;
|
||||||
|
cls.end = prev();
|
||||||
|
return subscripts(cls, allow_calls);
|
||||||
|
}
|
||||||
if (ATOMIC_START_TOKEN[S.token.type]) {
|
if (ATOMIC_START_TOKEN[S.token.type]) {
|
||||||
return subscripts(as_atom_node(), allow_calls);
|
return subscripts(as_atom_node(), allow_calls);
|
||||||
}
|
}
|
||||||
@@ -1446,32 +1464,9 @@ function parse($TEXT, options) {
|
|||||||
var type = start.type;
|
var type = start.type;
|
||||||
var name = as_property_name();
|
var name = as_property_name();
|
||||||
if (type != "string" && type != "num" && !is("punc", ":")) {
|
if (type != "string" && type != "num" && !is("punc", ":")) {
|
||||||
if (is("punc", "(")) {
|
var concise = concise_method_or_getset(name, start);
|
||||||
a.push(new AST_ConciseMethod({
|
if (concise) {
|
||||||
start : start,
|
a.push(concise);
|
||||||
name : new AST_SymbolMethod({ name: name }),
|
|
||||||
argnames : params_or_seq_().as_params(croak),
|
|
||||||
body : _function_body(true),
|
|
||||||
end : prev()
|
|
||||||
}))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (name == "get") {
|
|
||||||
a.push(new AST_ObjectGetter({
|
|
||||||
start : start,
|
|
||||||
key : as_atom_node(),
|
|
||||||
value : function_(AST_Accessor),
|
|
||||||
end : prev()
|
|
||||||
}));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (name == "set") {
|
|
||||||
a.push(new AST_ObjectSetter({
|
|
||||||
start : start,
|
|
||||||
key : as_atom_node(),
|
|
||||||
value : function_(AST_Accessor),
|
|
||||||
end : prev()
|
|
||||||
}));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1510,6 +1505,82 @@ function parse($TEXT, options) {
|
|||||||
return new AST_Object({ properties: a })
|
return new AST_Object({ properties: a })
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function class_(KindOfClass) {
|
||||||
|
var start, method, class_name, name, extends_, a = [];
|
||||||
|
|
||||||
|
if (S.token.type == "name" && S.token.value != "extends") {
|
||||||
|
class_name = as_symbol(KindOfClass === AST_DefClass ? AST_SymbolDefClass : AST_SymbolClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KindOfClass === AST_DefClass && !class_name) {
|
||||||
|
croak();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S.token.value == "extends") {
|
||||||
|
next();
|
||||||
|
extends_ = expression(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect("{");
|
||||||
|
|
||||||
|
if (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
|
||||||
|
while (!is("punc", "}")) {
|
||||||
|
start = S.token;
|
||||||
|
name = as_property_name();
|
||||||
|
method = concise_method_or_getset(name, start);
|
||||||
|
if (!method) { croak(); }
|
||||||
|
a.push(method);
|
||||||
|
if (is("punc", ";")) { next(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
|
||||||
|
return new KindOfClass({
|
||||||
|
start: start,
|
||||||
|
name: class_name,
|
||||||
|
extends: extends_,
|
||||||
|
properties: a,
|
||||||
|
end: prev(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function concise_method_or_getset(name, start) {
|
||||||
|
var is_static = false;
|
||||||
|
if (name === "static" && !is("punc", "(")) {
|
||||||
|
is_static = true;
|
||||||
|
name = S.token.value;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
if (is("punc", "(")) {
|
||||||
|
return new AST_ConciseMethod({
|
||||||
|
start : start,
|
||||||
|
static : is_static,
|
||||||
|
name : new AST_SymbolMethod({ name: name }),
|
||||||
|
argnames : params_or_seq_().as_params(croak),
|
||||||
|
body : _function_body(true),
|
||||||
|
end : prev()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (name == "get") {
|
||||||
|
return new AST_ObjectGetter({
|
||||||
|
start : start,
|
||||||
|
static: is_static,
|
||||||
|
key : as_atom_node(),
|
||||||
|
value : function_(AST_Accessor),
|
||||||
|
end : prev()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (name == "set") {
|
||||||
|
return new AST_ObjectSetter({
|
||||||
|
start : start,
|
||||||
|
static: is_static,
|
||||||
|
key : as_atom_node(),
|
||||||
|
value : function_(AST_Accessor),
|
||||||
|
end : prev()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function as_property_name() {
|
function as_property_name() {
|
||||||
var tmp = S.token;
|
var tmp = S.token;
|
||||||
next();
|
next();
|
||||||
|
|||||||
25
lib/scope.js
25
lib/scope.js
@@ -66,7 +66,11 @@ SymbolDef.prototype = {
|
|||||||
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
||||||
|| (options.keep_fnames
|
|| (options.keep_fnames
|
||||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
&& (this.orig[0] instanceof AST_SymbolLambda
|
||||||
|| this.orig[0] instanceof AST_SymbolDefun));
|
|| this.orig[0] instanceof AST_SymbolDefun))
|
||||||
|
|| this.orig[0] instanceof AST_SymbolMethod
|
||||||
|
|| (options.keep_classnames
|
||||||
|
&& (this.orig[0] instanceof AST_SymbolClass
|
||||||
|
|| this.orig[0] instanceof AST_SymbolDefClass));
|
||||||
},
|
},
|
||||||
mangle: function(options) {
|
mangle: function(options) {
|
||||||
var cache = options.cache && options.cache.props;
|
var cache = options.cache && options.cache.props;
|
||||||
@@ -155,6 +159,14 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
// later.
|
// later.
|
||||||
(node.scope = defun.parent_scope).def_function(node);
|
(node.scope = defun.parent_scope).def_function(node);
|
||||||
}
|
}
|
||||||
|
else if (node instanceof AST_SymbolClass) {
|
||||||
|
defun.def_variable(node);
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_SymbolDefClass) {
|
||||||
|
// This deals with the name of the class being available
|
||||||
|
// inside the class.
|
||||||
|
(node.scope = defun.parent_scope).def_function(node);
|
||||||
|
}
|
||||||
else if (node instanceof AST_SymbolVar
|
else if (node instanceof AST_SymbolVar
|
||||||
|| node instanceof AST_SymbolConst) {
|
|| node instanceof AST_SymbolConst) {
|
||||||
var def = defun.def_variable(node);
|
var def = defun.def_variable(node);
|
||||||
@@ -171,6 +183,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
|
|
||||||
// pass 2: find back references and eval
|
// pass 2: find back references and eval
|
||||||
var func = null;
|
var func = null;
|
||||||
|
var cls = null;
|
||||||
var globals = self.globals = new Dictionary();
|
var globals = self.globals = new Dictionary();
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (node instanceof AST_Lambda) {
|
if (node instanceof AST_Lambda) {
|
||||||
@@ -180,6 +193,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
func = prev_func;
|
func = prev_func;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_Class) {
|
||||||
|
var prev_cls = cls;
|
||||||
|
cls = node;
|
||||||
|
descend();
|
||||||
|
cls = prev_cls;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
var name = node.name;
|
var name = node.name;
|
||||||
var sym = node.scope.find_variable(name);
|
var sym = node.scope.find_variable(name);
|
||||||
@@ -363,7 +383,8 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
|||||||
sort : false,
|
sort : false,
|
||||||
toplevel : false,
|
toplevel : false,
|
||||||
screw_ie8 : false,
|
screw_ie8 : false,
|
||||||
keep_fnames : false
|
keep_fnames : false,
|
||||||
|
keep_classnames : false
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -181,6 +181,84 @@ concise_methods_and_keyword_names: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
classes: {
|
||||||
|
input: {
|
||||||
|
class SomeClass {
|
||||||
|
constructor() {
|
||||||
|
};
|
||||||
|
foo() {};
|
||||||
|
};
|
||||||
|
class NoSemi {
|
||||||
|
constructor(...args) {
|
||||||
|
}
|
||||||
|
foo() {}
|
||||||
|
};
|
||||||
|
class ChildClass extends SomeClass {};
|
||||||
|
var asExpression = class AsExpression {};
|
||||||
|
var nameless = class {};
|
||||||
|
}
|
||||||
|
expect_exact: "class SomeClass{constructor(){}foo(){}}class NoSemi{constructor(...args){}foo(){}}class ChildClass extends SomeClass{}var asExpression=class AsExpression{};var nameless=class{};"
|
||||||
|
}
|
||||||
|
|
||||||
|
class_statics: {
|
||||||
|
input: {
|
||||||
|
x = class {
|
||||||
|
static staticMethod() {}
|
||||||
|
static get foo() {}
|
||||||
|
static set bar() {}
|
||||||
|
static() { /* "static" can be a method name! */ }
|
||||||
|
get() { /* "get" can be a method name! */ }
|
||||||
|
set() { /* "set" can be a method name! */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "x=class{static staticMethod(){}static get foo(){}static set bar(){}static(){}get(){}set(){}};"
|
||||||
|
}
|
||||||
|
|
||||||
|
class_name_can_be_mangled: {
|
||||||
|
mangle = { };
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
class Foo {
|
||||||
|
}
|
||||||
|
var class1 = Foo
|
||||||
|
var class2 = class Bar {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
class a { }
|
||||||
|
var b = a
|
||||||
|
var c = class a {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class_name_can_be_preserved: {
|
||||||
|
mangle = {
|
||||||
|
keep_classnames: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
(class Baz { });
|
||||||
|
class Foo {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
(class Baz { });
|
||||||
|
class Foo {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_target: {
|
||||||
|
input: {
|
||||||
|
new.target;
|
||||||
|
new.target.name;
|
||||||
|
}
|
||||||
|
expect_exact: "new.target;new.target.name;"
|
||||||
|
}
|
||||||
|
|
||||||
number_literals: {
|
number_literals: {
|
||||||
input: {
|
input: {
|
||||||
0b1001;
|
0b1001;
|
||||||
|
|||||||
@@ -104,6 +104,9 @@ function run_compress_tests() {
|
|||||||
}
|
}
|
||||||
var output = input.transform(cmp);
|
var output = input.transform(cmp);
|
||||||
output.figure_out_scope();
|
output.figure_out_scope();
|
||||||
|
if (test.mangle) {
|
||||||
|
output.mangle_names(test.mangle);
|
||||||
|
}
|
||||||
output = make_code(output, false);
|
output = make_code(output, false);
|
||||||
if (expect != output) {
|
if (expect != output) {
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
|
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
|
||||||
|
|||||||
Reference in New Issue
Block a user