Merge pull request #25190 from mprobst/fix-generic-type-emit

Fix decorator design:types emit for type variables.
This commit is contained in:
Mohamed Hegazy
2018-06-26 14:04:37 -07:00
committed by GitHub
16 changed files with 254 additions and 10 deletions

View File

@@ -61,7 +61,8 @@ namespace ts {
let currentSourceFile: SourceFile;
let currentNamespace: ModuleDeclaration;
let currentNamespaceContainerName: Identifier;
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
let currentLexicalScope: SourceFile | Block | ModuleBlock | CaseBlock;
let currentNameScope: ClassDeclaration | undefined;
let currentScopeFirstDeclarationsOfName: UnderscoreEscapedMap<Node> | undefined;
/**
@@ -132,7 +133,8 @@ namespace ts {
*/
function saveStateAndInvoke<T>(node: Node, f: (node: Node) => T): T {
// Save state
const savedCurrentScope = currentScope;
const savedCurrentScope = currentLexicalScope;
const savedCurrentNameScope = currentNameScope;
const savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
// Handle state changes before visiting a node.
@@ -141,11 +143,12 @@ namespace ts {
const visited = f(node);
// Restore state
if (currentScope !== savedCurrentScope) {
if (currentLexicalScope !== savedCurrentScope) {
currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
}
currentScope = savedCurrentScope;
currentLexicalScope = savedCurrentScope;
currentNameScope = savedCurrentNameScope;
return visited;
}
@@ -160,7 +163,8 @@ namespace ts {
case SyntaxKind.CaseBlock:
case SyntaxKind.ModuleBlock:
case SyntaxKind.Block:
currentScope = <SourceFile | CaseBlock | ModuleBlock | Block>node;
currentLexicalScope = <SourceFile | CaseBlock | ModuleBlock | Block>node;
currentNameScope = undefined;
currentScopeFirstDeclarationsOfName = undefined;
break;
@@ -180,6 +184,10 @@ namespace ts {
// programs may also have an undefined name.
Debug.assert(node.kind === SyntaxKind.ClassDeclaration || hasModifier(node, ModifierFlags.Default));
}
if (isClassDeclaration(node)) {
// XXX: should probably also cover interfaces and type aliases that can have type variables?
currentNameScope = node;
}
break;
}
@@ -1971,7 +1979,7 @@ namespace ts {
* @param node The type reference node.
*/
function serializeTypeReferenceNode(node: TypeReferenceNode): SerializedTypeNode {
const kind = resolver.getTypeReferenceSerializationKind(node.typeName, currentScope);
const kind = resolver.getTypeReferenceSerializationKind(node.typeName, currentNameScope || currentLexicalScope);
switch (kind) {
case TypeReferenceSerializationKind.Unknown:
const serialized = serializeEntityNameAsExpression(node.typeName, /*useFallback*/ true);
@@ -2035,7 +2043,7 @@ namespace ts {
const name = getMutableClone(node);
name.flags &= ~NodeFlags.Synthesized;
name.original = undefined;
name.parent = getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
name.parent = getParseTreeNode(currentLexicalScope); // ensure the parent is set to a parse tree node.
if (useFallback) {
return createLogicalAnd(
createStrictInequality(
@@ -2622,7 +2630,7 @@ namespace ts {
// enum body.
if (addVarForEnumOrModuleDeclaration(statements, node)) {
// We should still emit the comments if we are emitting a system module.
if (moduleKind !== ModuleKind.System || currentScope !== currentSourceFile) {
if (moduleKind !== ModuleKind.System || currentLexicalScope !== currentSourceFile) {
emitFlags |= EmitFlags.NoLeadingComments;
}
}
@@ -2835,7 +2843,7 @@ namespace ts {
createVariableDeclaration(
getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)
)
], currentScope.kind === SyntaxKind.SourceFile ? NodeFlags.None : NodeFlags.Let)
], currentLexicalScope.kind === SyntaxKind.SourceFile ? NodeFlags.None : NodeFlags.Let)
);
setOriginalNode(statement, node);
@@ -2911,7 +2919,7 @@ namespace ts {
// module body.
if (addVarForEnumOrModuleDeclaration(statements, node)) {
// We should still emit the comments if we are emitting a system module.
if (moduleKind !== ModuleKind.System || currentScope !== currentSourceFile) {
if (moduleKind !== ModuleKind.System || currentLexicalScope !== currentSourceFile) {
emitFlags |= EmitFlags.NoLeadingComments;
}
}

View File

@@ -0,0 +1,11 @@
tests/cases/compiler/decoratorMetadataGenericTypeVariable.ts(2,4): error TS2304: Cannot find name 'Decorate'.
==== tests/cases/compiler/decoratorMetadataGenericTypeVariable.ts (1 errors) ====
export class C<TypeVariable> {
@Decorate
~~~~~~~~
!!! error TS2304: Cannot find name 'Decorate'.
member: TypeVariable;
}

View File

@@ -0,0 +1,29 @@
//// [decoratorMetadataGenericTypeVariable.ts]
export class C<TypeVariable> {
@Decorate
member: TypeVariable;
}
//// [decoratorMetadataGenericTypeVariable.js]
"use strict";
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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
exports.__esModule = true;
var C = /** @class */ (function () {
function C() {
}
__decorate([
Decorate,
__metadata("design:type", Object)
], C.prototype, "member");
return C;
}());
exports.C = C;

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/decoratorMetadataGenericTypeVariable.ts ===
export class C<TypeVariable> {
>C : Symbol(C, Decl(decoratorMetadataGenericTypeVariable.ts, 0, 0))
>TypeVariable : Symbol(TypeVariable, Decl(decoratorMetadataGenericTypeVariable.ts, 0, 15))
@Decorate
member: TypeVariable;
>member : Symbol(C.member, Decl(decoratorMetadataGenericTypeVariable.ts, 0, 30))
>TypeVariable : Symbol(TypeVariable, Decl(decoratorMetadataGenericTypeVariable.ts, 0, 15))
}

View File

@@ -0,0 +1,13 @@
=== tests/cases/compiler/decoratorMetadataGenericTypeVariable.ts ===
export class C<TypeVariable> {
>C : C<TypeVariable>
>TypeVariable : TypeVariable
@Decorate
>Decorate : any
member: TypeVariable;
>member : TypeVariable
>TypeVariable : TypeVariable
}

View File

@@ -0,0 +1,11 @@
tests/cases/compiler/decoratorMetadataGenericTypeVariableDefault.ts(2,4): error TS2304: Cannot find name 'Decorate'.
==== tests/cases/compiler/decoratorMetadataGenericTypeVariableDefault.ts (1 errors) ====
export class C<TypeVariable = string> {
@Decorate
~~~~~~~~
!!! error TS2304: Cannot find name 'Decorate'.
member: TypeVariable;
}

View File

@@ -0,0 +1,29 @@
//// [decoratorMetadataGenericTypeVariableDefault.ts]
export class C<TypeVariable = string> {
@Decorate
member: TypeVariable;
}
//// [decoratorMetadataGenericTypeVariableDefault.js]
"use strict";
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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
exports.__esModule = true;
var C = /** @class */ (function () {
function C() {
}
__decorate([
Decorate,
__metadata("design:type", Object)
], C.prototype, "member");
return C;
}());
exports.C = C;

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/decoratorMetadataGenericTypeVariableDefault.ts ===
export class C<TypeVariable = string> {
>C : Symbol(C, Decl(decoratorMetadataGenericTypeVariableDefault.ts, 0, 0))
>TypeVariable : Symbol(TypeVariable, Decl(decoratorMetadataGenericTypeVariableDefault.ts, 0, 15))
@Decorate
member: TypeVariable;
>member : Symbol(C.member, Decl(decoratorMetadataGenericTypeVariableDefault.ts, 0, 39))
>TypeVariable : Symbol(TypeVariable, Decl(decoratorMetadataGenericTypeVariableDefault.ts, 0, 15))
}

View File

@@ -0,0 +1,13 @@
=== tests/cases/compiler/decoratorMetadataGenericTypeVariableDefault.ts ===
export class C<TypeVariable = string> {
>C : C<TypeVariable>
>TypeVariable : TypeVariable
@Decorate
>Decorate : any
member: TypeVariable;
>member : TypeVariable
>TypeVariable : TypeVariable
}

View File

@@ -0,0 +1,14 @@
tests/cases/compiler/decoratorMetadataGenericTypeVariableInScope.ts(5,4): error TS2304: Cannot find name 'Decorate'.
==== tests/cases/compiler/decoratorMetadataGenericTypeVariableInScope.ts (1 errors) ====
// Unused, but could collide with the named type argument below.
class TypeVariable {}
export class C<TypeVariable> {
@Decorate
~~~~~~~~
!!! error TS2304: Cannot find name 'Decorate'.
member: TypeVariable;
}

View File

@@ -0,0 +1,38 @@
//// [decoratorMetadataGenericTypeVariableInScope.ts]
// Unused, but could collide with the named type argument below.
class TypeVariable {}
export class C<TypeVariable> {
@Decorate
member: TypeVariable;
}
//// [decoratorMetadataGenericTypeVariableInScope.js]
"use strict";
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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
exports.__esModule = true;
// Unused, but could collide with the named type argument below.
var TypeVariable = /** @class */ (function () {
function TypeVariable() {
}
return TypeVariable;
}());
var C = /** @class */ (function () {
function C() {
}
__decorate([
Decorate,
__metadata("design:type", Object)
], C.prototype, "member");
return C;
}());
exports.C = C;

View File

@@ -0,0 +1,15 @@
=== tests/cases/compiler/decoratorMetadataGenericTypeVariableInScope.ts ===
// Unused, but could collide with the named type argument below.
class TypeVariable {}
>TypeVariable : Symbol(TypeVariable, Decl(decoratorMetadataGenericTypeVariableInScope.ts, 0, 0))
export class C<TypeVariable> {
>C : Symbol(C, Decl(decoratorMetadataGenericTypeVariableInScope.ts, 1, 21))
>TypeVariable : Symbol(TypeVariable, Decl(decoratorMetadataGenericTypeVariableInScope.ts, 3, 15))
@Decorate
member: TypeVariable;
>member : Symbol(C.member, Decl(decoratorMetadataGenericTypeVariableInScope.ts, 3, 30))
>TypeVariable : Symbol(TypeVariable, Decl(decoratorMetadataGenericTypeVariableInScope.ts, 3, 15))
}

View File

@@ -0,0 +1,17 @@
=== tests/cases/compiler/decoratorMetadataGenericTypeVariableInScope.ts ===
// Unused, but could collide with the named type argument below.
class TypeVariable {}
>TypeVariable : TypeVariable
export class C<TypeVariable> {
>C : C<TypeVariable>
>TypeVariable : TypeVariable
@Decorate
>Decorate : any
member: TypeVariable;
>member : TypeVariable
>TypeVariable : TypeVariable
}

View File

@@ -0,0 +1,7 @@
// @experimentalDecorators: true
// @emitDecoratorMetadata: true
export class C<TypeVariable> {
@Decorate
member: TypeVariable;
}

View File

@@ -0,0 +1,7 @@
// @experimentalDecorators: true
// @emitDecoratorMetadata: true
export class C<TypeVariable = string> {
@Decorate
member: TypeVariable;
}

View File

@@ -0,0 +1,10 @@
// @experimentalDecorators: true
// @emitDecoratorMetadata: true
// Unused, but could collide with the named type argument below.
class TypeVariable {}
export class C<TypeVariable> {
@Decorate
member: TypeVariable;
}