From 1bb96555da2d6cfd0a0b5d7e6357ea50ce5c95d1 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 27 Jan 2016 16:13:51 -0800 Subject: [PATCH 1/3] Creates a class body scoped alias to the class to avoid class name double binding. Fixes #5386. --- src/compiler/checker.ts | 28 ++- src/compiler/emitter.ts | 180 ++++++++++++------ src/compiler/types.ts | 6 +- .../decoratedClassFromExternalModule.js | 2 +- .../decoratedDefaultExportsGetExportedAmd.js | 2 +- ...oratedDefaultExportsGetExportedCommonjs.js | 2 +- ...ecoratedDefaultExportsGetExportedSystem.js | 2 +- .../decoratedDefaultExportsGetExportedUmd.js | 2 +- .../reference/decoratorOnClass1.es6.js | 22 +++ .../reference/decoratorOnClass1.es6.symbols | 19 ++ .../reference/decoratorOnClass1.es6.types | 20 ++ .../reference/decoratorOnClass2.es6.js | 22 +++ .../reference/decoratorOnClass2.es6.symbols | 19 ++ .../reference/decoratorOnClass2.es6.types | 20 ++ .../reference/decoratorOnClass3.es6.js | 23 +++ .../reference/decoratorOnClass3.es6.symbols | 19 ++ .../reference/decoratorOnClass3.es6.types | 20 ++ .../reference/decoratorOnClass4.es6.js | 20 ++ .../reference/decoratorOnClass4.es6.symbols | 13 ++ .../reference/decoratorOnClass4.es6.types | 13 ++ .../reference/decoratorOnClass5.es6.js | 27 +++ .../reference/decoratorOnClass5.es6.symbols | 28 +++ .../reference/decoratorOnClass5.es6.types | 30 +++ .../reference/decoratorOnClass6.es6.js | 27 +++ .../reference/decoratorOnClass6.es6.symbols | 28 +++ .../reference/decoratorOnClass6.es6.types | 30 +++ .../reference/decoratorOnClass7.es6.js | 28 +++ .../reference/decoratorOnClass7.es6.symbols | 28 +++ .../reference/decoratorOnClass7.es6.types | 30 +++ .../reference/decoratorOnClass8.es6.js | 22 +++ .../reference/decoratorOnClass8.es6.symbols | 15 ++ .../reference/decoratorOnClass8.es6.types | 16 ++ .../reference/generatorTypeCheck39.js | 2 +- .../reference/generatorTypeCheck61.js | 2 +- .../decorators/class/decoratorOnClass1.es6.ts | 9 + .../decorators/class/decoratorOnClass2.es6.ts | 9 + .../decorators/class/decoratorOnClass3.es6.ts | 9 + .../decorators/class/decoratorOnClass4.es6.ts | 7 + .../decorators/class/decoratorOnClass5.es6.ts | 11 ++ .../decorators/class/decoratorOnClass6.es6.ts | 11 ++ .../decorators/class/decoratorOnClass7.es6.ts | 11 ++ .../decorators/class/decoratorOnClass8.es6.ts | 8 + 42 files changed, 771 insertions(+), 71 deletions(-) create mode 100644 tests/baselines/reference/decoratorOnClass1.es6.js create mode 100644 tests/baselines/reference/decoratorOnClass1.es6.symbols create mode 100644 tests/baselines/reference/decoratorOnClass1.es6.types create mode 100644 tests/baselines/reference/decoratorOnClass2.es6.js create mode 100644 tests/baselines/reference/decoratorOnClass2.es6.symbols create mode 100644 tests/baselines/reference/decoratorOnClass2.es6.types create mode 100644 tests/baselines/reference/decoratorOnClass3.es6.js create mode 100644 tests/baselines/reference/decoratorOnClass3.es6.symbols create mode 100644 tests/baselines/reference/decoratorOnClass3.es6.types create mode 100644 tests/baselines/reference/decoratorOnClass4.es6.js create mode 100644 tests/baselines/reference/decoratorOnClass4.es6.symbols create mode 100644 tests/baselines/reference/decoratorOnClass4.es6.types create mode 100644 tests/baselines/reference/decoratorOnClass5.es6.js create mode 100644 tests/baselines/reference/decoratorOnClass5.es6.symbols create mode 100644 tests/baselines/reference/decoratorOnClass5.es6.types create mode 100644 tests/baselines/reference/decoratorOnClass6.es6.js create mode 100644 tests/baselines/reference/decoratorOnClass6.es6.symbols create mode 100644 tests/baselines/reference/decoratorOnClass6.es6.types create mode 100644 tests/baselines/reference/decoratorOnClass7.es6.js create mode 100644 tests/baselines/reference/decoratorOnClass7.es6.symbols create mode 100644 tests/baselines/reference/decoratorOnClass7.es6.types create mode 100644 tests/baselines/reference/decoratorOnClass8.es6.js create mode 100644 tests/baselines/reference/decoratorOnClass8.es6.symbols create mode 100644 tests/baselines/reference/decoratorOnClass8.es6.types create mode 100644 tests/cases/conformance/es6/decorators/class/decoratorOnClass1.es6.ts create mode 100644 tests/cases/conformance/es6/decorators/class/decoratorOnClass2.es6.ts create mode 100644 tests/cases/conformance/es6/decorators/class/decoratorOnClass3.es6.ts create mode 100644 tests/cases/conformance/es6/decorators/class/decoratorOnClass4.es6.ts create mode 100644 tests/cases/conformance/es6/decorators/class/decoratorOnClass5.es6.ts create mode 100644 tests/cases/conformance/es6/decorators/class/decoratorOnClass6.es6.ts create mode 100644 tests/cases/conformance/es6/decorators/class/decoratorOnClass7.es6.ts create mode 100644 tests/cases/conformance/es6/decorators/class/decoratorOnClass8.es6.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e9211bb3e7e..2494d0db260 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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' diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 0a40047f686..a3dcf7d630e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -481,6 +481,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge let generatedNameSet: Map; 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(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ef6ae0168b1..cb48d9a3a8a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -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 */ diff --git a/tests/baselines/reference/decoratedClassFromExternalModule.js b/tests/baselines/reference/decoratedClassFromExternalModule.js index 000fe2f37d6..ce397323d9c 100644 --- a/tests/baselines/reference/decoratedClassFromExternalModule.js +++ b/tests/baselines/reference/decoratedClassFromExternalModule.js @@ -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 diff --git a/tests/baselines/reference/decoratedDefaultExportsGetExportedAmd.js b/tests/baselines/reference/decoratedDefaultExportsGetExportedAmd.js index dbbe72ba52c..14ede865a2f 100644 --- a/tests/baselines/reference/decoratedDefaultExportsGetExportedAmd.js +++ b/tests/baselines/reference/decoratedDefaultExportsGetExportedAmd.js @@ -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 diff --git a/tests/baselines/reference/decoratedDefaultExportsGetExportedCommonjs.js b/tests/baselines/reference/decoratedDefaultExportsGetExportedCommonjs.js index ab518d73cb9..ecc04859234 100644 --- a/tests/baselines/reference/decoratedDefaultExportsGetExportedCommonjs.js +++ b/tests/baselines/reference/decoratedDefaultExportsGetExportedCommonjs.js @@ -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 diff --git a/tests/baselines/reference/decoratedDefaultExportsGetExportedSystem.js b/tests/baselines/reference/decoratedDefaultExportsGetExportedSystem.js index ed322374799..eb5d9074651 100644 --- a/tests/baselines/reference/decoratedDefaultExportsGetExportedSystem.js +++ b/tests/baselines/reference/decoratedDefaultExportsGetExportedSystem.js @@ -25,7 +25,7 @@ System.register([], function(exports_1) { return { setters:[], execute: function() { - let Foo = class { + let Foo = class Foo { }; Foo = __decorate([ decorator diff --git a/tests/baselines/reference/decoratedDefaultExportsGetExportedUmd.js b/tests/baselines/reference/decoratedDefaultExportsGetExportedUmd.js index f8cb770f1d2..c7b59d01469 100644 --- a/tests/baselines/reference/decoratedDefaultExportsGetExportedUmd.js +++ b/tests/baselines/reference/decoratedDefaultExportsGetExportedUmd.js @@ -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 diff --git a/tests/baselines/reference/decoratorOnClass1.es6.js b/tests/baselines/reference/decoratorOnClass1.es6.js new file mode 100644 index 00000000000..7a02b9f5cd8 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass1.es6.js @@ -0,0 +1,22 @@ +//// [decoratorOnClass1.es6.ts] +declare function dec(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(); diff --git a/tests/baselines/reference/decoratorOnClass1.es6.symbols b/tests/baselines/reference/decoratorOnClass1.es6.symbols new file mode 100644 index 00000000000..aac2535d9cf --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass1.es6.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass1.es6.ts === +declare function dec(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)) + diff --git a/tests/baselines/reference/decoratorOnClass1.es6.types b/tests/baselines/reference/decoratorOnClass1.es6.types new file mode 100644 index 00000000000..fe7ef79ea62 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass1.es6.types @@ -0,0 +1,20 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass1.es6.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +>T : T +>target : T +>T : T +>T : T + +@dec +>dec : (target: T) => T + +class C { +>C : C +} + +let c = new C(); +>c : C +>new C() : C +>C : typeof C + diff --git a/tests/baselines/reference/decoratorOnClass2.es6.js b/tests/baselines/reference/decoratorOnClass2.es6.js new file mode 100644 index 00000000000..872f241bc9c --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass2.es6.js @@ -0,0 +1,22 @@ +//// [decoratorOnClass2.es6.ts] +declare function dec(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(); diff --git a/tests/baselines/reference/decoratorOnClass2.es6.symbols b/tests/baselines/reference/decoratorOnClass2.es6.symbols new file mode 100644 index 00000000000..af0dc7c1fad --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass2.es6.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass2.es6.ts === +declare function dec(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)) + diff --git a/tests/baselines/reference/decoratorOnClass2.es6.types b/tests/baselines/reference/decoratorOnClass2.es6.types new file mode 100644 index 00000000000..2845ab1b977 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass2.es6.types @@ -0,0 +1,20 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass2.es6.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +>T : T +>target : T +>T : T +>T : T + +@dec +>dec : (target: T) => T + +export class C { +>C : C +} + +let c = new C(); +>c : C +>new C() : C +>C : typeof C + diff --git a/tests/baselines/reference/decoratorOnClass3.es6.js b/tests/baselines/reference/decoratorOnClass3.es6.js new file mode 100644 index 00000000000..a6b1d6e2589 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass3.es6.js @@ -0,0 +1,23 @@ +//// [decoratorOnClass3.es6.ts] +declare function dec(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(); diff --git a/tests/baselines/reference/decoratorOnClass3.es6.symbols b/tests/baselines/reference/decoratorOnClass3.es6.symbols new file mode 100644 index 00000000000..d769d1c97a1 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass3.es6.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass3.es6.ts === +declare function dec(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)) + diff --git a/tests/baselines/reference/decoratorOnClass3.es6.types b/tests/baselines/reference/decoratorOnClass3.es6.types new file mode 100644 index 00000000000..7b19c4bad8e --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass3.es6.types @@ -0,0 +1,20 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass3.es6.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +>T : T +>target : T +>T : T +>T : T + +@dec +>dec : (target: T) => T + +export default class C { +>C : C +} + +let c = new C(); +>c : C +>new C() : C +>C : typeof C + diff --git a/tests/baselines/reference/decoratorOnClass4.es6.js b/tests/baselines/reference/decoratorOnClass4.es6.js new file mode 100644 index 00000000000..0435c822da6 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass4.es6.js @@ -0,0 +1,20 @@ +//// [decoratorOnClass4.es6.ts] +declare function dec(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; diff --git a/tests/baselines/reference/decoratorOnClass4.es6.symbols b/tests/baselines/reference/decoratorOnClass4.es6.symbols new file mode 100644 index 00000000000..fff39c72f1c --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass4.es6.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass4.es6.ts === +declare function dec(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 { +} diff --git a/tests/baselines/reference/decoratorOnClass4.es6.types b/tests/baselines/reference/decoratorOnClass4.es6.types new file mode 100644 index 00000000000..7dfce858076 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass4.es6.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass4.es6.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +>T : T +>target : T +>T : T +>T : T + +@dec +>dec : (target: T) => T + +export default class { +} diff --git a/tests/baselines/reference/decoratorOnClass5.es6.js b/tests/baselines/reference/decoratorOnClass5.es6.js new file mode 100644 index 00000000000..58c5f0d4f29 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass5.es6.js @@ -0,0 +1,27 @@ +//// [decoratorOnClass5.es6.ts] +declare function dec(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(); diff --git a/tests/baselines/reference/decoratorOnClass5.es6.symbols b/tests/baselines/reference/decoratorOnClass5.es6.symbols new file mode 100644 index 00000000000..aa62a593019 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass5.es6.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass5.es6.ts === +declare function dec(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)) + diff --git a/tests/baselines/reference/decoratorOnClass5.es6.types b/tests/baselines/reference/decoratorOnClass5.es6.types new file mode 100644 index 00000000000..5532c50fe52 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass5.es6.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass5.es6.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +>T : T +>target : T +>T : T +>T : T + +@dec +>dec : (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 + diff --git a/tests/baselines/reference/decoratorOnClass6.es6.js b/tests/baselines/reference/decoratorOnClass6.es6.js new file mode 100644 index 00000000000..03b8ace2b5b --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass6.es6.js @@ -0,0 +1,27 @@ +//// [decoratorOnClass6.es6.ts] +declare function dec(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(); diff --git a/tests/baselines/reference/decoratorOnClass6.es6.symbols b/tests/baselines/reference/decoratorOnClass6.es6.symbols new file mode 100644 index 00000000000..f778128e40b --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass6.es6.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass6.es6.ts === +declare function dec(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)) + diff --git a/tests/baselines/reference/decoratorOnClass6.es6.types b/tests/baselines/reference/decoratorOnClass6.es6.types new file mode 100644 index 00000000000..0b335558400 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass6.es6.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass6.es6.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +>T : T +>target : T +>T : T +>T : T + +@dec +>dec : (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 + diff --git a/tests/baselines/reference/decoratorOnClass7.es6.js b/tests/baselines/reference/decoratorOnClass7.es6.js new file mode 100644 index 00000000000..3ffd0f1574f --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass7.es6.js @@ -0,0 +1,28 @@ +//// [decoratorOnClass7.es6.ts] +declare function dec(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(); diff --git a/tests/baselines/reference/decoratorOnClass7.es6.symbols b/tests/baselines/reference/decoratorOnClass7.es6.symbols new file mode 100644 index 00000000000..d010757a9df --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass7.es6.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass7.es6.ts === +declare function dec(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)) + diff --git a/tests/baselines/reference/decoratorOnClass7.es6.types b/tests/baselines/reference/decoratorOnClass7.es6.types new file mode 100644 index 00000000000..af7ae0516e3 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass7.es6.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass7.es6.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +>T : T +>target : T +>T : T +>T : T + +@dec +>dec : (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 + diff --git a/tests/baselines/reference/decoratorOnClass8.es6.js b/tests/baselines/reference/decoratorOnClass8.es6.js new file mode 100644 index 00000000000..7104098a5f5 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass8.es6.js @@ -0,0 +1,22 @@ +//// [decoratorOnClass8.es6.ts] +declare function dec(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; diff --git a/tests/baselines/reference/decoratorOnClass8.es6.symbols b/tests/baselines/reference/decoratorOnClass8.es6.symbols new file mode 100644 index 00000000000..b219f50ff3d --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass8.es6.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass8.es6.ts === +declare function dec(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)) +} diff --git a/tests/baselines/reference/decoratorOnClass8.es6.types b/tests/baselines/reference/decoratorOnClass8.es6.types new file mode 100644 index 00000000000..045b036e335 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass8.es6.types @@ -0,0 +1,16 @@ +=== tests/cases/conformance/es6/decorators/class/decoratorOnClass8.es6.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +>T : T +>target : T +>T : T +>T : T + +@dec +>dec : (target: T) => T + +export default class { + static y = 1; +>y : number +>1 : number +} diff --git a/tests/baselines/reference/generatorTypeCheck39.js b/tests/baselines/reference/generatorTypeCheck39.js index 43df3b8e205..1e0009d24ed 100644 --- a/tests/baselines/reference/generatorTypeCheck39.js +++ b/tests/baselines/reference/generatorTypeCheck39.js @@ -20,7 +20,7 @@ function decorator(x) { return y => { }; } function* g() { - let C = class { + let C = class C { constructor() { this.x = yield 0; } diff --git a/tests/baselines/reference/generatorTypeCheck61.js b/tests/baselines/reference/generatorTypeCheck61.js index b2434ee590c..9cc157f2684 100644 --- a/tests/baselines/reference/generatorTypeCheck61.js +++ b/tests/baselines/reference/generatorTypeCheck61.js @@ -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) diff --git a/tests/cases/conformance/es6/decorators/class/decoratorOnClass1.es6.ts b/tests/cases/conformance/es6/decorators/class/decoratorOnClass1.es6.ts new file mode 100644 index 00000000000..7dccedc5d1f --- /dev/null +++ b/tests/cases/conformance/es6/decorators/class/decoratorOnClass1.es6.ts @@ -0,0 +1,9 @@ +// @target:es6 +// @experimentaldecorators: true +declare function dec(target: T): T; + +@dec +class C { +} + +let c = new C(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/decorators/class/decoratorOnClass2.es6.ts b/tests/cases/conformance/es6/decorators/class/decoratorOnClass2.es6.ts new file mode 100644 index 00000000000..62d6a15d0bc --- /dev/null +++ b/tests/cases/conformance/es6/decorators/class/decoratorOnClass2.es6.ts @@ -0,0 +1,9 @@ +// @target:es6 +// @experimentaldecorators: true +declare function dec(target: T): T; + +@dec +export class C { +} + +let c = new C(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/decorators/class/decoratorOnClass3.es6.ts b/tests/cases/conformance/es6/decorators/class/decoratorOnClass3.es6.ts new file mode 100644 index 00000000000..cc62befe2d8 --- /dev/null +++ b/tests/cases/conformance/es6/decorators/class/decoratorOnClass3.es6.ts @@ -0,0 +1,9 @@ +// @target:es6 +// @experimentaldecorators: true +declare function dec(target: T): T; + +@dec +export default class C { +} + +let c = new C(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/decorators/class/decoratorOnClass4.es6.ts b/tests/cases/conformance/es6/decorators/class/decoratorOnClass4.es6.ts new file mode 100644 index 00000000000..050c8ae15fc --- /dev/null +++ b/tests/cases/conformance/es6/decorators/class/decoratorOnClass4.es6.ts @@ -0,0 +1,7 @@ +// @target:es6 +// @experimentaldecorators: true +declare function dec(target: T): T; + +@dec +export default class { +} \ No newline at end of file diff --git a/tests/cases/conformance/es6/decorators/class/decoratorOnClass5.es6.ts b/tests/cases/conformance/es6/decorators/class/decoratorOnClass5.es6.ts new file mode 100644 index 00000000000..daa21330c2b --- /dev/null +++ b/tests/cases/conformance/es6/decorators/class/decoratorOnClass5.es6.ts @@ -0,0 +1,11 @@ +// @target:es6 +// @experimentaldecorators: true +declare function dec(target: T): T; + +@dec +class C { + static x() { return C.y; } + static y = 1; +} + +let c = new C(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/decorators/class/decoratorOnClass6.es6.ts b/tests/cases/conformance/es6/decorators/class/decoratorOnClass6.es6.ts new file mode 100644 index 00000000000..b28f8918495 --- /dev/null +++ b/tests/cases/conformance/es6/decorators/class/decoratorOnClass6.es6.ts @@ -0,0 +1,11 @@ +// @target:es6 +// @experimentaldecorators: true +declare function dec(target: T): T; + +@dec +export class C { + static x() { return C.y; } + static y = 1; +} + +let c = new C(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/decorators/class/decoratorOnClass7.es6.ts b/tests/cases/conformance/es6/decorators/class/decoratorOnClass7.es6.ts new file mode 100644 index 00000000000..a69b7556d97 --- /dev/null +++ b/tests/cases/conformance/es6/decorators/class/decoratorOnClass7.es6.ts @@ -0,0 +1,11 @@ +// @target:es6 +// @experimentaldecorators: true +declare function dec(target: T): T; + +@dec +export default class C { + static x() { return C.y; } + static y = 1; +} + +let c = new C(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/decorators/class/decoratorOnClass8.es6.ts b/tests/cases/conformance/es6/decorators/class/decoratorOnClass8.es6.ts new file mode 100644 index 00000000000..2e85fc801f2 --- /dev/null +++ b/tests/cases/conformance/es6/decorators/class/decoratorOnClass8.es6.ts @@ -0,0 +1,8 @@ +// @target:es6 +// @experimentaldecorators: true +declare function dec(target: T): T; + +@dec +export default class { + static y = 1; +} \ No newline at end of file From 098d59c954d3ba4c48abaae5708a85246cc264e0 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 27 Jan 2016 16:33:45 -0800 Subject: [PATCH 2/3] Cleaned up variable names and conditions in checkIdentifier --- src/compiler/checker.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2494d0db260..11f550bad5b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7192,19 +7192,18 @@ namespace ts { markAliasSymbolAsReferenced(symbol); } - const localSymbol = getExportSymbolOfValueSymbolIfExported(symbol); + const localOrExportSymbol = 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)) { + && localOrExportSymbol.flags & SymbolFlags.Class + && localOrExportSymbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration + && nodeIsDecorated(localOrExportSymbol.valueDeclaration)) { let container = getContainingClass(node); while (container !== undefined) { - if (container === localSymbol.valueDeclaration && container.name !== node) { + if (container === localOrExportSymbol.valueDeclaration && container.name !== node) { getNodeLinks(container).flags |= NodeCheckFlags.ClassWithBodyScopedClassBinding; getNodeLinks(node).flags |= NodeCheckFlags.BodyScopedClassBinding; break; @@ -7218,7 +7217,7 @@ namespace ts { checkCollisionWithCapturedThisVariable(node, node); checkNestedBlockScopedBinding(node, symbol); - return getNarrowedTypeOfSymbol(localSymbol, node); + return getNarrowedTypeOfSymbol(localOrExportSymbol, node); } function isInsideFunction(node: Node, threshold: Node): boolean { From 39077f686636494454d9f85b36aae07eb5736c27 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 28 Jan 2016 15:25:42 -0800 Subject: [PATCH 3/3] PR feedback --- src/compiler/emitter.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index a3dcf7d630e..0a3cbd89d9e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1544,7 +1544,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge // 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) { + if (declaration) { const classAlias = decoratedClassAliases[getNodeId(declaration)]; if (classAlias !== undefined) { write(classAlias); @@ -5195,13 +5195,6 @@ const _super = (function (geti, seti) { // // 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; }