Skip to content

Commit

Permalink
Merge pull request #11391 from Microsoft/metaDataWithStringLiteral
Browse files Browse the repository at this point in the history
Emit of union type metadata for decorator to use constituent serialized type if its identifier and same across all constituent types
  • Loading branch information
sheetalkamat committed Oct 6, 2016
2 parents 3008520 + 506afe5 commit 7555f60
Show file tree
Hide file tree
Showing 9 changed files with 409 additions and 2 deletions.
35 changes: 33 additions & 2 deletions src/compiler/transformers/ts.ts
Expand Up @@ -1801,10 +1801,41 @@ namespace ts {
case SyntaxKind.TypeReference:
return serializeTypeReferenceNode(<TypeReferenceNode>node);

case SyntaxKind.IntersectionType:
case SyntaxKind.UnionType:
{
const unionOrIntersection = <UnionOrIntersectionTypeNode>node;
let serializedUnion: Identifier;
for (const typeNode of unionOrIntersection.types) {
const serializedIndividual = serializeTypeNode(typeNode) as Identifier;
// Non identifier
if (serializedIndividual.kind !== SyntaxKind.Identifier) {
serializedUnion = undefined;
break;
}

// One of the individual is global object, return immediately
if (serializedIndividual.text === "Object") {
return serializedIndividual;
}

// Different types
if (serializedUnion && serializedUnion.text !== serializedIndividual.text) {
serializedUnion = undefined;
break;
}

serializedUnion = serializedIndividual;
}

// If we were able to find common type
if (serializedUnion) {
return serializedUnion;
}
}
// Fallthrough
case SyntaxKind.TypeQuery:
case SyntaxKind.TypeLiteral:
case SyntaxKind.UnionType:
case SyntaxKind.IntersectionType:
case SyntaxKind.AnyKeyword:
case SyntaxKind.ThisType:
break;
Expand Down
28 changes: 28 additions & 0 deletions tests/baselines/reference/metadataOfStringLiteral.js
@@ -0,0 +1,28 @@
//// [metadataOfStringLiteral.ts]
function PropDeco(target: Object, propKey: string | symbol) { }

class Foo {
@PropDeco
public foo: "foo" | "bar";
}

//// [metadataOfStringLiteral.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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
function PropDeco(target, propKey) { }
var Foo = (function () {
function Foo() {
}
return Foo;
}());
__decorate([
PropDeco,
__metadata("design:type", String)
], Foo.prototype, "foo");
16 changes: 16 additions & 0 deletions tests/baselines/reference/metadataOfStringLiteral.symbols
@@ -0,0 +1,16 @@
=== tests/cases/compiler/metadataOfStringLiteral.ts ===
function PropDeco(target: Object, propKey: string | symbol) { }
>PropDeco : Symbol(PropDeco, Decl(metadataOfStringLiteral.ts, 0, 0))
>target : Symbol(target, Decl(metadataOfStringLiteral.ts, 0, 18))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>propKey : Symbol(propKey, Decl(metadataOfStringLiteral.ts, 0, 33))

class Foo {
>Foo : Symbol(Foo, Decl(metadataOfStringLiteral.ts, 0, 63))

@PropDeco
>PropDeco : Symbol(PropDeco, Decl(metadataOfStringLiteral.ts, 0, 0))

public foo: "foo" | "bar";
>foo : Symbol(Foo.foo, Decl(metadataOfStringLiteral.ts, 2, 11))
}
16 changes: 16 additions & 0 deletions tests/baselines/reference/metadataOfStringLiteral.types
@@ -0,0 +1,16 @@
=== tests/cases/compiler/metadataOfStringLiteral.ts ===
function PropDeco(target: Object, propKey: string | symbol) { }
>PropDeco : (target: Object, propKey: string | symbol) => void
>target : Object
>Object : Object
>propKey : string | symbol

class Foo {
>Foo : Foo

@PropDeco
>PropDeco : (target: Object, propKey: string | symbol) => void

public foo: "foo" | "bar";
>foo : "foo" | "bar"
}
99 changes: 99 additions & 0 deletions tests/baselines/reference/metadataOfUnion.js
@@ -0,0 +1,99 @@
//// [metadataOfUnion.ts]
function PropDeco(target: Object, propKey: string | symbol) { }

class A {
}

class B {
@PropDeco
x: "foo" | A;

@PropDeco
y: true | boolean;

@PropDeco
z: "foo" | boolean;
}

enum E {
A,
B,
C,
D
}

class D {
@PropDeco
a: E.A;

@PropDeco
b: E.B | E.C;

@PropDeco
c: E;

@PropDeco
d: E | number;
}

//// [metadataOfUnion.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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
function PropDeco(target, propKey) { }
var A = (function () {
function A() {
}
return A;
}());
var B = (function () {
function B() {
}
return B;
}());
__decorate([
PropDeco,
__metadata("design:type", Object)
], B.prototype, "x");
__decorate([
PropDeco,
__metadata("design:type", Boolean)
], B.prototype, "y");
__decorate([
PropDeco,
__metadata("design:type", Object)
], B.prototype, "z");
var E;
(function (E) {
E[E["A"] = 0] = "A";
E[E["B"] = 1] = "B";
E[E["C"] = 2] = "C";
E[E["D"] = 3] = "D";
})(E || (E = {}));
var D = (function () {
function D() {
}
return D;
}());
__decorate([
PropDeco,
__metadata("design:type", Number)
], D.prototype, "a");
__decorate([
PropDeco,
__metadata("design:type", Number)
], D.prototype, "b");
__decorate([
PropDeco,
__metadata("design:type", Number)
], D.prototype, "c");
__decorate([
PropDeco,
__metadata("design:type", Number)
], D.prototype, "d");
85 changes: 85 additions & 0 deletions tests/baselines/reference/metadataOfUnion.symbols
@@ -0,0 +1,85 @@
=== tests/cases/compiler/metadataOfUnion.ts ===
function PropDeco(target: Object, propKey: string | symbol) { }
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))
>target : Symbol(target, Decl(metadataOfUnion.ts, 0, 18))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>propKey : Symbol(propKey, Decl(metadataOfUnion.ts, 0, 33))

class A {
>A : Symbol(A, Decl(metadataOfUnion.ts, 0, 63))
}

class B {
>B : Symbol(B, Decl(metadataOfUnion.ts, 3, 1))

@PropDeco
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))

x: "foo" | A;
>x : Symbol(B.x, Decl(metadataOfUnion.ts, 5, 9))
>A : Symbol(A, Decl(metadataOfUnion.ts, 0, 63))

@PropDeco
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))

y: true | boolean;
>y : Symbol(B.y, Decl(metadataOfUnion.ts, 7, 17))

@PropDeco
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))

z: "foo" | boolean;
>z : Symbol(B.z, Decl(metadataOfUnion.ts, 10, 22))
}

enum E {
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))

A,
>A : Symbol(E.A, Decl(metadataOfUnion.ts, 16, 8))

B,
>B : Symbol(E.B, Decl(metadataOfUnion.ts, 17, 6))

C,
>C : Symbol(E.C, Decl(metadataOfUnion.ts, 18, 6))

D
>D : Symbol(E.D, Decl(metadataOfUnion.ts, 19, 6))
}

class D {
>D : Symbol(D, Decl(metadataOfUnion.ts, 21, 1))

@PropDeco
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))

a: E.A;
>a : Symbol(D.a, Decl(metadataOfUnion.ts, 23, 9))
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
>A : Symbol(E.A, Decl(metadataOfUnion.ts, 16, 8))

@PropDeco
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))

b: E.B | E.C;
>b : Symbol(D.b, Decl(metadataOfUnion.ts, 25, 11))
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
>B : Symbol(E.B, Decl(metadataOfUnion.ts, 17, 6))
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
>C : Symbol(E.C, Decl(metadataOfUnion.ts, 18, 6))

@PropDeco
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))

c: E;
>c : Symbol(D.c, Decl(metadataOfUnion.ts, 28, 17))
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))

@PropDeco
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))

d: E | number;
>d : Symbol(D.d, Decl(metadataOfUnion.ts, 31, 9))
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
}
86 changes: 86 additions & 0 deletions tests/baselines/reference/metadataOfUnion.types
@@ -0,0 +1,86 @@
=== tests/cases/compiler/metadataOfUnion.ts ===
function PropDeco(target: Object, propKey: string | symbol) { }
>PropDeco : (target: Object, propKey: string | symbol) => void
>target : Object
>Object : Object
>propKey : string | symbol

class A {
>A : A
}

class B {
>B : B

@PropDeco
>PropDeco : (target: Object, propKey: string | symbol) => void

x: "foo" | A;
>x : A | "foo"
>A : A

@PropDeco
>PropDeco : (target: Object, propKey: string | symbol) => void

y: true | boolean;
>y : boolean
>true : true

@PropDeco
>PropDeco : (target: Object, propKey: string | symbol) => void

z: "foo" | boolean;
>z : boolean | "foo"
}

enum E {
>E : E

A,
>A : E.A

B,
>B : E.B

C,
>C : E.C

D
>D : E.D
}

class D {
>D : D

@PropDeco
>PropDeco : (target: Object, propKey: string | symbol) => void

a: E.A;
>a : E.A
>E : any
>A : E.A

@PropDeco
>PropDeco : (target: Object, propKey: string | symbol) => void

b: E.B | E.C;
>b : E.B | E.C
>E : any
>B : E.B
>E : any
>C : E.C

@PropDeco
>PropDeco : (target: Object, propKey: string | symbol) => void

c: E;
>c : E
>E : E

@PropDeco
>PropDeco : (target: Object, propKey: string | symbol) => void

d: E | number;
>d : number | E
>E : E
}
8 changes: 8 additions & 0 deletions tests/cases/compiler/metadataOfStringLiteral.ts
@@ -0,0 +1,8 @@
// @experimentalDecorators: true
// @emitDecoratorMetadata: true
function PropDeco(target: Object, propKey: string | symbol) { }

class Foo {
@PropDeco
public foo: "foo" | "bar";
}

0 comments on commit 7555f60

Please sign in to comment.