Creates a class body scoped alias to the class to avoid class name double binding.

Fixes #5386.
This commit is contained in:
Ron Buckton
2016-01-27 16:13:51 -08:00
parent 6648403a8e
commit 1bb96555da
42 changed files with 771 additions and 71 deletions
+25 -3
View File
@@ -7192,11 +7192,33 @@ namespace ts {
markAliasSymbolAsReferenced(symbol);
}
const localSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
// behavior of class names in ES6.
if (languageVersion === ScriptTarget.ES6
&& localSymbol
&& localSymbol.valueDeclaration
&& localSymbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration
&& nodeIsDecorated(localSymbol.valueDeclaration)) {
let container = getContainingClass(node);
while (container !== undefined) {
if (container === localSymbol.valueDeclaration && container.name !== node) {
getNodeLinks(container).flags |= NodeCheckFlags.ClassWithBodyScopedClassBinding;
getNodeLinks(node).flags |= NodeCheckFlags.BodyScopedClassBinding;
break;
}
container = getContainingClass(container);
}
}
checkCollisionWithCapturedSuperVariable(node, node);
checkCollisionWithCapturedThisVariable(node, node);
checkNestedBlockScopedBinding(node, symbol);
return getNarrowedTypeOfSymbol(getExportSymbolOfValueSymbolIfExported(symbol), node);
return getNarrowedTypeOfSymbol(localSymbol, node);
}
function isInsideFunction(node: Node, threshold: Node): boolean {
@@ -7238,7 +7260,7 @@ namespace ts {
if (containedInIterationStatement) {
if (usedInFunction) {
// mark iteration statement as containing block-scoped binding captured in some function
// mark iteration statement as containing block-scoped binding captured in some function
getNodeLinks(current).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
}
// set 'declared inside loop' bit on the block-scoped binding
@@ -15734,7 +15756,7 @@ namespace ts {
// - binding is not top level - top level bindings never collide with anything
// AND
// - binding is not declared in loop, should be renamed to avoid name reuse across siblings
// let a, b
// let a, b
// { let x = 1; a = () => x; }
// { let x = 100; b = () => x; }
// console.log(a()); // should print '1'
+121 -59
View File
@@ -481,6 +481,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
let generatedNameSet: Map<string>;
let nodeToGeneratedName: string[];
let computedPropertyNamesToGeneratedNames: string[];
let decoratedClassAliases: string[];
let convertedLoopState: ConvertedLoopState;
@@ -531,6 +532,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
generatedNameSet = {};
nodeToGeneratedName = [];
decoratedClassAliases = [];
isOwnFileEmit = !isBundledEmit;
// Emit helpers from all the files
@@ -559,6 +561,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
exportFunctionForFile = undefined;
generatedNameSet = undefined;
nodeToGeneratedName = undefined;
decoratedClassAliases = undefined;
computedPropertyNamesToGeneratedNames = undefined;
convertedLoopState = undefined;
extendsEmitted = false;
@@ -1529,13 +1532,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
}
}
if (languageVersion !== ScriptTarget.ES6) {
if (languageVersion < ScriptTarget.ES6) {
const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
if (declaration) {
write(getGeneratedNameForNode(declaration.name));
return;
}
}
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.BodyScopedClassBinding) {
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
// behavior of class names in ES6.
const declaration = resolver.getReferencedValueDeclaration(node);
if (declaration && declaration.kind === SyntaxKind.ClassDeclaration) {
const classAlias = decoratedClassAliases[getNodeId(declaration)];
if (classAlias !== undefined) {
write(classAlias);
return;
}
}
}
}
if (nodeIsSynthesized(node)) {
@@ -4067,7 +4083,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
let initializer = node.initializer;
if (!initializer &&
languageVersion < ScriptTarget.ES6 &&
// for names - binding patterns that lack initializer there is no point to emit explicit initializer
// for names - binding patterns that lack initializer there is no point to emit explicit initializer
// since downlevel codegen for destructuring will fail in the absence of initializer so all binding elements will say uninitialized
node.name.kind === SyntaxKind.Identifier) {
@@ -4088,11 +4104,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
// explicitly initialized. One particular case: non-captured binding declared inside loop body (but not in loop initializer)
// let x;
// for (;;) {
// let x;
// let x;
// }
// in downlevel codegen inner 'x' will be renamed so it won't collide with outer 'x' however it will should be reset on every iteration
// as if it was declared anew.
// * Why non-captured binding - because if loop contains block scoped binding captured in some function then loop body will be rewritten
// as if it was declared anew.
// * Why non-captured binding - because if loop contains block scoped binding captured in some function then loop body will be rewritten
// to have a fresh scope on every iteration so everything will just work.
// * Why loop initializer is excluded - since we've introduced a fresh name it already will be undefined.
const isCapturedInFunction = flags & NodeCheckFlags.CapturedBlockScopedBinding;
@@ -5106,64 +5122,114 @@ const _super = (function (geti, seti) {
}
function emitClassLikeDeclarationForES6AndHigher(node: ClassLikeDeclaration) {
let decoratedClassAlias: string;
const thisNodeIsDecorated = nodeIsDecorated(node);
if (node.kind === SyntaxKind.ClassDeclaration) {
if (thisNodeIsDecorated) {
// To preserve the correct runtime semantics when decorators are applied to the class,
// the emit needs to follow one of the following rules:
// When we emit an ES6 class that has a class decorator, we must tailor the
// emit to certain specific cases.
//
// * For a local class declaration:
// In the simplest case, we emit the class declaration as a let declaration, and
// evaluate decorators after the close of the class body:
//
// @dec class C {
// }
// TypeScript | Javascript
// --------------------------------|------------------------------------
// @dec | let C = class C {
// class C { | }
// } | C = __decorate([dec], C);
// --------------------------------|------------------------------------
// @dec | export let C = class C {
// export class C { | }
// } | C = __decorate([dec], C);
// ---------------------------------------------------------------------
// [Example 1]
//
// The emit should be:
// If a class declaration contains a reference to itself *inside* of the class body,
// this introduces two bindings to the class: One outside of the class body, and one
// inside of the class body. If we apply decorators as in [Example 1] above, there
// is the possibility that the decorator `dec` will return a new value for the
// constructor, which would result in the binding inside of the class no longer
// pointing to the same reference as the binding outside of the class.
//
// let C = class {
// };
// C = __decorate([dec], C);
// As a result, we must instead rewrite all references to the class *inside* of the
// class body to instead point to a local temporary alias for the class:
//
// * For an exported class declaration:
// TypeScript | Javascript
// --------------------------------|------------------------------------
// @dec | let C_1;
// class C { | let C = C_1 = class C {
// static x() { return C.y; } | static x() { return C_1.y; }
// static y = 1; | }
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// --------------------------------|------------------------------------
// @dec | let C_1;
// export class C { | export let C = C_1 = class C {
// static x() { return C.y; } | static x() { return C_1.y; }
// static y = 1; | }
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// ---------------------------------------------------------------------
// [Example 2]
//
// @dec export class C {
// }
// If a class declaration is the default export of a module, we instead emit
// the export after the decorated declaration:
//
// The emit should be:
// TypeScript | Javascript
// --------------------------------|------------------------------------
// @dec | let default_1 = class {
// export default class { | }
// } | default_1 = __decorate([dec], default_1);
// | export default default_1;
// --------------------------------|------------------------------------
// @dec | let C = class C {
// export default class { | }
// } | C = __decorate([dec], C);
// | export default C;
// ---------------------------------------------------------------------
// [Example 3]
//
// export let C = class {
// };
// C = __decorate([dec], C);
// If the class declaration is the default export and a reference to itself
// inside of the class body, we must emit both an alias for the class *and*
// move the export after the declaration:
//
// * For a default export of a class declaration with a name:
//
// @dec default export class C {
// }
//
// The emit should be:
//
// let C = class {
// }
// C = __decorate([dec], C);
// export default C;
//
// * For a default export of a class declaration without a name:
//
// @dec default export class {
// }
//
// The emit should be:
//
// let _default = class {
// }
// _default = __decorate([dec], _default);
// export default _default;
// TypeScript | Javascript
// --------------------------------|------------------------------------
// @dec | let default_1 = class {
// export default class { | static x() { return default_1.y; }
// static x() { return C.y; } | }
// static y = 1; | default_1.y = 1;
// } | default_1 = __decorate([dec], default_1);
// | export default default_1;
// --------------------------------|------------------------------------
// @dec | let C_1;
// export default class C { | let C = C_1 = class C {
// static x() { return C.y; } | static x() { return C_1.y; }
// static y = 1; | }
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// | export default C;
// ---------------------------------------------------------------------
// [Example 4]
//
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithBodyScopedClassBinding) {
decoratedClassAlias = unescapeIdentifier(makeUniqueName(node.name ? node.name.text : "default"));
decoratedClassAliases[getNodeId(node)] = decoratedClassAlias;
write(`let ${decoratedClassAlias};`);
writeLine();
}
if (isES6ExportedDeclaration(node) && !(node.flags & NodeFlags.Default)) {
write("export ");
}
write("let ");
emitDeclarationName(node);
if (decoratedClassAlias !== undefined) {
write(` = ${decoratedClassAlias}`);
}
write(" = ");
}
else if (isES6ExportedDeclaration(node)) {
@@ -5202,7 +5268,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) && !thisNodeIsDecorated)) {
write(" ");
emitDeclarationName(node);
}
@@ -5222,16 +5288,8 @@ const _super = (function (geti, seti) {
writeLine();
emitToken(SyntaxKind.CloseBraceToken, node.members.end);
// TODO(rbuckton): Need to go back to `let _a = class C {}` approach, removing the defineProperty call for now.
// For a decorated class, we need to assign its name (if it has one). This is because we emit
// the class as a class expression to avoid the double-binding of the identifier:
//
// let C = class {
// }
// Object.defineProperty(C, "name", { value: "C", configurable: true });
//
if (thisNodeIsDecorated) {
decoratedClassAliases[getNodeId(node)] = undefined;
write(";");
}
@@ -5256,7 +5314,7 @@ const _super = (function (geti, seti) {
else {
writeLine();
emitPropertyDeclarations(node, staticProperties);
emitDecoratorsOfClass(node);
emitDecoratorsOfClass(node, decoratedClassAlias);
}
if (!(node.flags & NodeFlags.Export)) {
@@ -5330,7 +5388,7 @@ const _super = (function (geti, seti) {
emitMemberFunctionsForES5AndLower(node);
emitPropertyDeclarations(node, getInitializedProperties(node, /*isStatic*/ true));
writeLine();
emitDecoratorsOfClass(node);
emitDecoratorsOfClass(node, /*decoratedClassAlias*/ undefined);
writeLine();
emitToken(SyntaxKind.CloseBraceToken, node.members.end, () => {
write("return ");
@@ -5372,13 +5430,13 @@ const _super = (function (geti, seti) {
}
}
function emitDecoratorsOfClass(node: ClassLikeDeclaration) {
function emitDecoratorsOfClass(node: ClassLikeDeclaration, decoratedClassAlias: string) {
emitDecoratorsOfMembers(node, /*staticFlag*/ 0);
emitDecoratorsOfMembers(node, NodeFlags.Static);
emitDecoratorsOfConstructor(node);
emitDecoratorsOfConstructor(node, decoratedClassAlias);
}
function emitDecoratorsOfConstructor(node: ClassLikeDeclaration) {
function emitDecoratorsOfConstructor(node: ClassLikeDeclaration, decoratedClassAlias: string) {
const decorators = node.decorators;
const constructor = getFirstConstructorWithBody(node);
const firstParameterDecorator = constructor && forEach(constructor.parameters, parameter => parameter.decorators);
@@ -5402,6 +5460,10 @@ const _super = (function (geti, seti) {
writeLine();
emitStart(node.decorators || firstParameterDecorator);
emitDeclarationName(node);
if (decoratedClassAlias !== undefined) {
write(` = ${decoratedClassAlias}`);
}
write(" = __decorate([");
increaseIndent();
writeLine();
+4 -2
View File
@@ -2068,8 +2068,10 @@ namespace ts {
EnumValuesComputed = 0x00004000,
LexicalModuleMergesWithClass = 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
ClassWithBodyScopedClassBinding = 0x00080000, // Decorated class that contains a binding to itself inside of the class body.
BodyScopedClassBinding = 0x00100000, // Binding to a decorated class inside of the class's body.
}
/* @internal */
@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
function decorate(target) { }
let Decorated = class {
let Decorated = class Decorated {
};
Decorated = __decorate([
decorate
@@ -23,7 +23,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
define(["require", "exports"], function (require, exports) {
"use strict";
var decorator;
let Foo = class {
let Foo = class Foo {
};
Foo = __decorate([
decorator
@@ -22,7 +22,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var decorator;
let Foo = class {
let Foo = class Foo {
};
Foo = __decorate([
decorator
@@ -25,7 +25,7 @@ System.register([], function(exports_1) {
return {
setters:[],
execute: function() {
let Foo = class {
let Foo = class Foo {
};
Foo = __decorate([
decorator
@@ -30,7 +30,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
})(function (require, exports) {
"use strict";
var decorator;
let Foo = class {
let Foo = class Foo {
};
Foo = __decorate([
decorator
@@ -0,0 +1,22 @@
//// [decoratorOnClass1.es6.ts]
declare function dec<T>(target: T): T;
@dec
class C {
}
let c = new C();
//// [decoratorOnClass1.es6.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let C = class C {
};
C = __decorate([
dec
], C);
let c = new C();
@@ -0,0 +1,19 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass1.es6.ts ===
declare function dec<T>(target: T): T;
>dec : Symbol(dec, Decl(decoratorOnClass1.es6.ts, 0, 0))
>T : Symbol(T, Decl(decoratorOnClass1.es6.ts, 0, 21))
>target : Symbol(target, Decl(decoratorOnClass1.es6.ts, 0, 24))
>T : Symbol(T, Decl(decoratorOnClass1.es6.ts, 0, 21))
>T : Symbol(T, Decl(decoratorOnClass1.es6.ts, 0, 21))
@dec
>dec : Symbol(dec, Decl(decoratorOnClass1.es6.ts, 0, 0))
class C {
>C : Symbol(C, Decl(decoratorOnClass1.es6.ts, 0, 38))
}
let c = new C();
>c : Symbol(c, Decl(decoratorOnClass1.es6.ts, 6, 3))
>C : Symbol(C, Decl(decoratorOnClass1.es6.ts, 0, 38))
@@ -0,0 +1,20 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass1.es6.ts ===
declare function dec<T>(target: T): T;
>dec : <T>(target: T) => T
>T : T
>target : T
>T : T
>T : T
@dec
>dec : <T>(target: T) => T
class C {
>C : C
}
let c = new C();
>c : C
>new C() : C
>C : typeof C
@@ -0,0 +1,22 @@
//// [decoratorOnClass2.es6.ts]
declare function dec<T>(target: T): T;
@dec
export class C {
}
let c = new C();
//// [decoratorOnClass2.es6.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
export let C = class C {
};
C = __decorate([
dec
], C);
let c = new C();
@@ -0,0 +1,19 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass2.es6.ts ===
declare function dec<T>(target: T): T;
>dec : Symbol(dec, Decl(decoratorOnClass2.es6.ts, 0, 0))
>T : Symbol(T, Decl(decoratorOnClass2.es6.ts, 0, 21))
>target : Symbol(target, Decl(decoratorOnClass2.es6.ts, 0, 24))
>T : Symbol(T, Decl(decoratorOnClass2.es6.ts, 0, 21))
>T : Symbol(T, Decl(decoratorOnClass2.es6.ts, 0, 21))
@dec
>dec : Symbol(dec, Decl(decoratorOnClass2.es6.ts, 0, 0))
export class C {
>C : Symbol(C, Decl(decoratorOnClass2.es6.ts, 0, 38))
}
let c = new C();
>c : Symbol(c, Decl(decoratorOnClass2.es6.ts, 6, 3))
>C : Symbol(C, Decl(decoratorOnClass2.es6.ts, 0, 38))
@@ -0,0 +1,20 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass2.es6.ts ===
declare function dec<T>(target: T): T;
>dec : <T>(target: T) => T
>T : T
>target : T
>T : T
>T : T
@dec
>dec : <T>(target: T) => T
export class C {
>C : C
}
let c = new C();
>c : C
>new C() : C
>C : typeof C
@@ -0,0 +1,23 @@
//// [decoratorOnClass3.es6.ts]
declare function dec<T>(target: T): T;
@dec
export default class C {
}
let c = new C();
//// [decoratorOnClass3.es6.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let C = class C {
};
C = __decorate([
dec
], C);
export default C;
let c = new C();
@@ -0,0 +1,19 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass3.es6.ts ===
declare function dec<T>(target: T): T;
>dec : Symbol(dec, Decl(decoratorOnClass3.es6.ts, 0, 0))
>T : Symbol(T, Decl(decoratorOnClass3.es6.ts, 0, 21))
>target : Symbol(target, Decl(decoratorOnClass3.es6.ts, 0, 24))
>T : Symbol(T, Decl(decoratorOnClass3.es6.ts, 0, 21))
>T : Symbol(T, Decl(decoratorOnClass3.es6.ts, 0, 21))
@dec
>dec : Symbol(dec, Decl(decoratorOnClass3.es6.ts, 0, 0))
export default class C {
>C : Symbol(C, Decl(decoratorOnClass3.es6.ts, 0, 38))
}
let c = new C();
>c : Symbol(c, Decl(decoratorOnClass3.es6.ts, 6, 3))
>C : Symbol(C, Decl(decoratorOnClass3.es6.ts, 0, 38))
@@ -0,0 +1,20 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass3.es6.ts ===
declare function dec<T>(target: T): T;
>dec : <T>(target: T) => T
>T : T
>target : T
>T : T
>T : T
@dec
>dec : <T>(target: T) => T
export default class C {
>C : C
}
let c = new C();
>c : C
>new C() : C
>C : typeof C
@@ -0,0 +1,20 @@
//// [decoratorOnClass4.es6.ts]
declare function dec<T>(target: T): T;
@dec
export default class {
}
//// [decoratorOnClass4.es6.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let default_1 = class {
};
default_1 = __decorate([
dec
], default_1);
export default default_1;
@@ -0,0 +1,13 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass4.es6.ts ===
declare function dec<T>(target: T): T;
>dec : Symbol(dec, Decl(decoratorOnClass4.es6.ts, 0, 0))
>T : Symbol(T, Decl(decoratorOnClass4.es6.ts, 0, 21))
>target : Symbol(target, Decl(decoratorOnClass4.es6.ts, 0, 24))
>T : Symbol(T, Decl(decoratorOnClass4.es6.ts, 0, 21))
>T : Symbol(T, Decl(decoratorOnClass4.es6.ts, 0, 21))
@dec
>dec : Symbol(dec, Decl(decoratorOnClass4.es6.ts, 0, 0))
export default class {
}
@@ -0,0 +1,13 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass4.es6.ts ===
declare function dec<T>(target: T): T;
>dec : <T>(target: T) => T
>T : T
>target : T
>T : T
>T : T
@dec
>dec : <T>(target: T) => T
export default class {
}
@@ -0,0 +1,27 @@
//// [decoratorOnClass5.es6.ts]
declare function dec<T>(target: T): T;
@dec
class C {
static x() { return C.y; }
static y = 1;
}
let c = new C();
//// [decoratorOnClass5.es6.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let C_1;
let C = C_1 = class C {
static x() { return C_1.y; }
};
C.y = 1;
C = C_1 = __decorate([
dec
], C);
let c = new C();
@@ -0,0 +1,28 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass5.es6.ts ===
declare function dec<T>(target: T): T;
>dec : Symbol(dec, Decl(decoratorOnClass5.es6.ts, 0, 0))
>T : Symbol(T, Decl(decoratorOnClass5.es6.ts, 0, 21))
>target : Symbol(target, Decl(decoratorOnClass5.es6.ts, 0, 24))
>T : Symbol(T, Decl(decoratorOnClass5.es6.ts, 0, 21))
>T : Symbol(T, Decl(decoratorOnClass5.es6.ts, 0, 21))
@dec
>dec : Symbol(dec, Decl(decoratorOnClass5.es6.ts, 0, 0))
class C {
>C : Symbol(C, Decl(decoratorOnClass5.es6.ts, 0, 38))
static x() { return C.y; }
>x : Symbol(C.x, Decl(decoratorOnClass5.es6.ts, 3, 9))
>C.y : Symbol(C.y, Decl(decoratorOnClass5.es6.ts, 4, 30))
>C : Symbol(C, Decl(decoratorOnClass5.es6.ts, 0, 38))
>y : Symbol(C.y, Decl(decoratorOnClass5.es6.ts, 4, 30))
static y = 1;
>y : Symbol(C.y, Decl(decoratorOnClass5.es6.ts, 4, 30))
}
let c = new C();
>c : Symbol(c, Decl(decoratorOnClass5.es6.ts, 8, 3))
>C : Symbol(C, Decl(decoratorOnClass5.es6.ts, 0, 38))
@@ -0,0 +1,30 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass5.es6.ts ===
declare function dec<T>(target: T): T;
>dec : <T>(target: T) => T
>T : T
>target : T
>T : T
>T : T
@dec
>dec : <T>(target: T) => T
class C {
>C : C
static x() { return C.y; }
>x : () => number
>C.y : number
>C : typeof C
>y : number
static y = 1;
>y : number
>1 : number
}
let c = new C();
>c : C
>new C() : C
>C : typeof C
@@ -0,0 +1,27 @@
//// [decoratorOnClass6.es6.ts]
declare function dec<T>(target: T): T;
@dec
export class C {
static x() { return C.y; }
static y = 1;
}
let c = new C();
//// [decoratorOnClass6.es6.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let C_1;
export let C = C_1 = class C {
static x() { return C_1.y; }
};
C.y = 1;
C = C_1 = __decorate([
dec
], C);
let c = new C();
@@ -0,0 +1,28 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass6.es6.ts ===
declare function dec<T>(target: T): T;
>dec : Symbol(dec, Decl(decoratorOnClass6.es6.ts, 0, 0))
>T : Symbol(T, Decl(decoratorOnClass6.es6.ts, 0, 21))
>target : Symbol(target, Decl(decoratorOnClass6.es6.ts, 0, 24))
>T : Symbol(T, Decl(decoratorOnClass6.es6.ts, 0, 21))
>T : Symbol(T, Decl(decoratorOnClass6.es6.ts, 0, 21))
@dec
>dec : Symbol(dec, Decl(decoratorOnClass6.es6.ts, 0, 0))
export class C {
>C : Symbol(C, Decl(decoratorOnClass6.es6.ts, 0, 38))
static x() { return C.y; }
>x : Symbol(C.x, Decl(decoratorOnClass6.es6.ts, 3, 16))
>C.y : Symbol(C.y, Decl(decoratorOnClass6.es6.ts, 4, 30))
>C : Symbol(C, Decl(decoratorOnClass6.es6.ts, 0, 38))
>y : Symbol(C.y, Decl(decoratorOnClass6.es6.ts, 4, 30))
static y = 1;
>y : Symbol(C.y, Decl(decoratorOnClass6.es6.ts, 4, 30))
}
let c = new C();
>c : Symbol(c, Decl(decoratorOnClass6.es6.ts, 8, 3))
>C : Symbol(C, Decl(decoratorOnClass6.es6.ts, 0, 38))
@@ -0,0 +1,30 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass6.es6.ts ===
declare function dec<T>(target: T): T;
>dec : <T>(target: T) => T
>T : T
>target : T
>T : T
>T : T
@dec
>dec : <T>(target: T) => T
export class C {
>C : C
static x() { return C.y; }
>x : () => number
>C.y : number
>C : typeof C
>y : number
static y = 1;
>y : number
>1 : number
}
let c = new C();
>c : C
>new C() : C
>C : typeof C
@@ -0,0 +1,28 @@
//// [decoratorOnClass7.es6.ts]
declare function dec<T>(target: T): T;
@dec
export default class C {
static x() { return C.y; }
static y = 1;
}
let c = new C();
//// [decoratorOnClass7.es6.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let C_1;
let C = C_1 = class C {
static x() { return C_1.y; }
};
C.y = 1;
C = C_1 = __decorate([
dec
], C);
export default C;
let c = new C();
@@ -0,0 +1,28 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass7.es6.ts ===
declare function dec<T>(target: T): T;
>dec : Symbol(dec, Decl(decoratorOnClass7.es6.ts, 0, 0))
>T : Symbol(T, Decl(decoratorOnClass7.es6.ts, 0, 21))
>target : Symbol(target, Decl(decoratorOnClass7.es6.ts, 0, 24))
>T : Symbol(T, Decl(decoratorOnClass7.es6.ts, 0, 21))
>T : Symbol(T, Decl(decoratorOnClass7.es6.ts, 0, 21))
@dec
>dec : Symbol(dec, Decl(decoratorOnClass7.es6.ts, 0, 0))
export default class C {
>C : Symbol(C, Decl(decoratorOnClass7.es6.ts, 0, 38))
static x() { return C.y; }
>x : Symbol(C.x, Decl(decoratorOnClass7.es6.ts, 3, 24))
>C.y : Symbol(C.y, Decl(decoratorOnClass7.es6.ts, 4, 30))
>C : Symbol(C, Decl(decoratorOnClass7.es6.ts, 0, 38))
>y : Symbol(C.y, Decl(decoratorOnClass7.es6.ts, 4, 30))
static y = 1;
>y : Symbol(C.y, Decl(decoratorOnClass7.es6.ts, 4, 30))
}
let c = new C();
>c : Symbol(c, Decl(decoratorOnClass7.es6.ts, 8, 3))
>C : Symbol(C, Decl(decoratorOnClass7.es6.ts, 0, 38))
@@ -0,0 +1,30 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass7.es6.ts ===
declare function dec<T>(target: T): T;
>dec : <T>(target: T) => T
>T : T
>target : T
>T : T
>T : T
@dec
>dec : <T>(target: T) => T
export default class C {
>C : C
static x() { return C.y; }
>x : () => number
>C.y : number
>C : typeof C
>y : number
static y = 1;
>y : number
>1 : number
}
let c = new C();
>c : C
>new C() : C
>C : typeof C
@@ -0,0 +1,22 @@
//// [decoratorOnClass8.es6.ts]
declare function dec<T>(target: T): T;
@dec
export default class {
static y = 1;
}
//// [decoratorOnClass8.es6.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let default_1 = class {
};
default_1.y = 1;
default_1 = __decorate([
dec
], default_1);
export default default_1;
@@ -0,0 +1,15 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass8.es6.ts ===
declare function dec<T>(target: T): T;
>dec : Symbol(dec, Decl(decoratorOnClass8.es6.ts, 0, 0))
>T : Symbol(T, Decl(decoratorOnClass8.es6.ts, 0, 21))
>target : Symbol(target, Decl(decoratorOnClass8.es6.ts, 0, 24))
>T : Symbol(T, Decl(decoratorOnClass8.es6.ts, 0, 21))
>T : Symbol(T, Decl(decoratorOnClass8.es6.ts, 0, 21))
@dec
>dec : Symbol(dec, Decl(decoratorOnClass8.es6.ts, 0, 0))
export default class {
static y = 1;
>y : Symbol(default.y, Decl(decoratorOnClass8.es6.ts, 3, 22))
}
@@ -0,0 +1,16 @@
=== tests/cases/conformance/es6/decorators/class/decoratorOnClass8.es6.ts ===
declare function dec<T>(target: T): T;
>dec : <T>(target: T) => T
>T : T
>target : T
>T : T
>T : T
@dec
>dec : <T>(target: T) => T
export default class {
static y = 1;
>y : number
>1 : number
}
@@ -20,7 +20,7 @@ function decorator(x) {
return y => { };
}
function* g() {
let C = class {
let C = class C {
constructor() {
this.x = yield 0;
}
@@ -12,7 +12,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
function* g() {
let C = class {
let C = class C {
};
C = __decorate([
(yield 0)
@@ -0,0 +1,9 @@
// @target:es6
// @experimentaldecorators: true
declare function dec<T>(target: T): T;
@dec
class C {
}
let c = new C();
@@ -0,0 +1,9 @@
// @target:es6
// @experimentaldecorators: true
declare function dec<T>(target: T): T;
@dec
export class C {
}
let c = new C();
@@ -0,0 +1,9 @@
// @target:es6
// @experimentaldecorators: true
declare function dec<T>(target: T): T;
@dec
export default class C {
}
let c = new C();
@@ -0,0 +1,7 @@
// @target:es6
// @experimentaldecorators: true
declare function dec<T>(target: T): T;
@dec
export default class {
}
@@ -0,0 +1,11 @@
// @target:es6
// @experimentaldecorators: true
declare function dec<T>(target: T): T;
@dec
class C {
static x() { return C.y; }
static y = 1;
}
let c = new C();
@@ -0,0 +1,11 @@
// @target:es6
// @experimentaldecorators: true
declare function dec<T>(target: T): T;
@dec
export class C {
static x() { return C.y; }
static y = 1;
}
let c = new C();
@@ -0,0 +1,11 @@
// @target:es6
// @experimentaldecorators: true
declare function dec<T>(target: T): T;
@dec
export default class C {
static x() { return C.y; }
static y = 1;
}
let c = new C();
@@ -0,0 +1,8 @@
// @target:es6
// @experimentaldecorators: true
declare function dec<T>(target: T): T;
@dec
export default class {
static y = 1;
}