mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-07-02 14:48:32 -05:00
emit top level classes as class expressions when target=ES6 and module=System
This commit is contained in:
@@ -5278,9 +5278,11 @@ const _super = (function (geti, seti) {
|
||||
|
||||
function emitClassLikeDeclarationForES6AndHigher(node: ClassLikeDeclaration) {
|
||||
let decoratedClassAlias: string;
|
||||
const thisNodeIsDecorated = nodeIsDecorated(node);
|
||||
const isHoistedDeclarationInSystemModule = shouldHoistDeclarationInSystemJsModule(node);
|
||||
const isDecorated = nodeIsDecorated(node);
|
||||
const rewriteAsClassExpression = isDecorated || isHoistedDeclarationInSystemModule;
|
||||
if (node.kind === SyntaxKind.ClassDeclaration) {
|
||||
if (thisNodeIsDecorated) {
|
||||
if (rewriteAsClassExpression) {
|
||||
// When we emit an ES6 class that has a class decorator, we must tailor the
|
||||
// emit to certain specific cases.
|
||||
//
|
||||
@@ -5361,7 +5363,10 @@ const _super = (function (geti, seti) {
|
||||
// [Example 4]
|
||||
//
|
||||
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithBodyScopedClassBinding) {
|
||||
// NOTE: we reuse the same rewriting logic for cases when targeting ES6 and module kind is System.
|
||||
// Because of hoisting top level class declaration need to be emitted as class expressions.
|
||||
// Double bind case is only required if node is decorated.
|
||||
if (isDecorated && resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithBodyScopedClassBinding) {
|
||||
decoratedClassAlias = unescapeIdentifier(makeUniqueName(node.name ? node.name.text : "default"));
|
||||
decoratedClassAliases[getNodeId(node)] = decoratedClassAlias;
|
||||
write(`let ${decoratedClassAlias};`);
|
||||
@@ -5372,7 +5377,9 @@ const _super = (function (geti, seti) {
|
||||
write("export ");
|
||||
}
|
||||
|
||||
write("let ");
|
||||
if (!isHoistedDeclarationInSystemModule) {
|
||||
write("let ");
|
||||
}
|
||||
emitDeclarationName(node);
|
||||
if (decoratedClassAlias !== undefined) {
|
||||
write(` = ${decoratedClassAlias}`);
|
||||
@@ -5416,7 +5423,7 @@ const _super = (function (geti, seti) {
|
||||
// emit name if
|
||||
// - node has a name
|
||||
// - this is default export with static initializers
|
||||
if (node.name || (node.flags & NodeFlags.Default && (staticProperties.length > 0 || modulekind !== ModuleKind.ES6) && !thisNodeIsDecorated)) {
|
||||
if (node.name || (node.flags & NodeFlags.Default && (staticProperties.length > 0 || modulekind !== ModuleKind.ES6) && !rewriteAsClassExpression)) {
|
||||
write(" ");
|
||||
emitDeclarationName(node);
|
||||
}
|
||||
@@ -5436,7 +5443,7 @@ const _super = (function (geti, seti) {
|
||||
writeLine();
|
||||
emitToken(SyntaxKind.CloseBraceToken, node.members.end);
|
||||
|
||||
if (thisNodeIsDecorated) {
|
||||
if (rewriteAsClassExpression) {
|
||||
decoratedClassAliases[getNodeId(node)] = undefined;
|
||||
write(";");
|
||||
}
|
||||
@@ -5476,7 +5483,7 @@ const _super = (function (geti, seti) {
|
||||
// module), export it
|
||||
if (node.flags & NodeFlags.Default) {
|
||||
// if this is a top level default export of decorated class, write the export after the declaration.
|
||||
if (thisNodeIsDecorated) {
|
||||
if (isDecorated) {
|
||||
writeLine();
|
||||
write("export default ");
|
||||
emitDeclarationName(node);
|
||||
|
||||
@@ -14,8 +14,8 @@ System.register([], function(exports_1, context_1) {
|
||||
return {
|
||||
setters:[],
|
||||
execute: function() {
|
||||
class default_1 {
|
||||
}
|
||||
default_1 = class {
|
||||
};
|
||||
exports_1("default", default_1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ System.register([], function(exports_1, context_1) {
|
||||
return {
|
||||
setters:[],
|
||||
execute: function() {
|
||||
let Foo = class Foo {
|
||||
Foo = class Foo {
|
||||
};
|
||||
Foo = __decorate([
|
||||
decorator
|
||||
@@ -49,7 +49,7 @@ System.register([], function(exports_1, context_1) {
|
||||
return {
|
||||
setters:[],
|
||||
execute: function() {
|
||||
let default_1 = class {
|
||||
default_1 = class {
|
||||
};
|
||||
default_1 = __decorate([
|
||||
decorator
|
||||
|
||||
@@ -15,8 +15,8 @@ System.register([], function(exports_1, context_1) {
|
||||
return {
|
||||
setters:[],
|
||||
execute: function() {
|
||||
class Foo {
|
||||
}
|
||||
Foo = class Foo {
|
||||
};
|
||||
exports_1("default", Foo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ System.register("a", ["b"], function(exports_2, context_2) {
|
||||
b_1 = b_1_1;
|
||||
}],
|
||||
execute: function() {
|
||||
class Foo {
|
||||
}
|
||||
Foo = class Foo {
|
||||
};
|
||||
exports_2("default", Foo);
|
||||
b_1.default();
|
||||
}
|
||||
|
||||
42
tests/baselines/reference/systemModuleTargetES6.js
Normal file
42
tests/baselines/reference/systemModuleTargetES6.js
Normal file
@@ -0,0 +1,42 @@
|
||||
//// [systemModuleTargetES6.ts]
|
||||
export class MyClass { }
|
||||
export class MyClass2 {
|
||||
static value = 42;
|
||||
static getInstance() { return MyClass2.value; }
|
||||
}
|
||||
|
||||
export function myFunction() {
|
||||
return new MyClass();
|
||||
}
|
||||
|
||||
export function myFunction2() {
|
||||
return new MyClass2();
|
||||
}
|
||||
|
||||
//// [systemModuleTargetES6.js]
|
||||
System.register([], function(exports_1, context_1) {
|
||||
"use strict";
|
||||
var __moduleName = context_1 && context_1.id;
|
||||
var MyClass, MyClass2;
|
||||
function myFunction() {
|
||||
return new MyClass();
|
||||
}
|
||||
exports_1("myFunction", myFunction);
|
||||
function myFunction2() {
|
||||
return new MyClass2();
|
||||
}
|
||||
exports_1("myFunction2", myFunction2);
|
||||
return {
|
||||
setters:[],
|
||||
execute: function() {
|
||||
MyClass = class MyClass {
|
||||
};
|
||||
exports_1("MyClass", MyClass);
|
||||
MyClass2 = class MyClass2 {
|
||||
static getInstance() { return MyClass2.value; }
|
||||
};
|
||||
MyClass2.value = 42;
|
||||
exports_1("MyClass2", MyClass2);
|
||||
}
|
||||
}
|
||||
});
|
||||
30
tests/baselines/reference/systemModuleTargetES6.symbols
Normal file
30
tests/baselines/reference/systemModuleTargetES6.symbols
Normal file
@@ -0,0 +1,30 @@
|
||||
=== tests/cases/compiler/systemModuleTargetES6.ts ===
|
||||
export class MyClass { }
|
||||
>MyClass : Symbol(MyClass, Decl(systemModuleTargetES6.ts, 0, 0))
|
||||
|
||||
export class MyClass2 {
|
||||
>MyClass2 : Symbol(MyClass2, Decl(systemModuleTargetES6.ts, 0, 24))
|
||||
|
||||
static value = 42;
|
||||
>value : Symbol(MyClass2.value, Decl(systemModuleTargetES6.ts, 1, 23))
|
||||
|
||||
static getInstance() { return MyClass2.value; }
|
||||
>getInstance : Symbol(MyClass2.getInstance, Decl(systemModuleTargetES6.ts, 2, 22))
|
||||
>MyClass2.value : Symbol(MyClass2.value, Decl(systemModuleTargetES6.ts, 1, 23))
|
||||
>MyClass2 : Symbol(MyClass2, Decl(systemModuleTargetES6.ts, 0, 24))
|
||||
>value : Symbol(MyClass2.value, Decl(systemModuleTargetES6.ts, 1, 23))
|
||||
}
|
||||
|
||||
export function myFunction() {
|
||||
>myFunction : Symbol(myFunction, Decl(systemModuleTargetES6.ts, 4, 1))
|
||||
|
||||
return new MyClass();
|
||||
>MyClass : Symbol(MyClass, Decl(systemModuleTargetES6.ts, 0, 0))
|
||||
}
|
||||
|
||||
export function myFunction2() {
|
||||
>myFunction2 : Symbol(myFunction2, Decl(systemModuleTargetES6.ts, 8, 1))
|
||||
|
||||
return new MyClass2();
|
||||
>MyClass2 : Symbol(MyClass2, Decl(systemModuleTargetES6.ts, 0, 24))
|
||||
}
|
||||
33
tests/baselines/reference/systemModuleTargetES6.types
Normal file
33
tests/baselines/reference/systemModuleTargetES6.types
Normal file
@@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/systemModuleTargetES6.ts ===
|
||||
export class MyClass { }
|
||||
>MyClass : MyClass
|
||||
|
||||
export class MyClass2 {
|
||||
>MyClass2 : MyClass2
|
||||
|
||||
static value = 42;
|
||||
>value : number
|
||||
>42 : number
|
||||
|
||||
static getInstance() { return MyClass2.value; }
|
||||
>getInstance : () => number
|
||||
>MyClass2.value : number
|
||||
>MyClass2 : typeof MyClass2
|
||||
>value : number
|
||||
}
|
||||
|
||||
export function myFunction() {
|
||||
>myFunction : () => MyClass
|
||||
|
||||
return new MyClass();
|
||||
>new MyClass() : MyClass
|
||||
>MyClass : typeof MyClass
|
||||
}
|
||||
|
||||
export function myFunction2() {
|
||||
>myFunction2 : () => MyClass2
|
||||
|
||||
return new MyClass2();
|
||||
>new MyClass2() : MyClass2
|
||||
>MyClass2 : typeof MyClass2
|
||||
}
|
||||
15
tests/cases/compiler/systemModuleTargetES6.ts
Normal file
15
tests/cases/compiler/systemModuleTargetES6.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// @target: ES6
|
||||
// @module: System
|
||||
export class MyClass { }
|
||||
export class MyClass2 {
|
||||
static value = 42;
|
||||
static getInstance() { return MyClass2.value; }
|
||||
}
|
||||
|
||||
export function myFunction() {
|
||||
return new MyClass();
|
||||
}
|
||||
|
||||
export function myFunction2() {
|
||||
return new MyClass2();
|
||||
}
|
||||
Reference in New Issue
Block a user