From c40234fe9687d5e504a752e31e4f17e275423d78 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 4 Oct 2016 16:52:39 -0700 Subject: [PATCH 1/4] Adding test for emit of metadata for string literal union --- .../reference/metadataOfStringLiteral.js | 28 +++++++++++++++++++ .../reference/metadataOfStringLiteral.symbols | 16 +++++++++++ .../reference/metadataOfStringLiteral.types | 16 +++++++++++ .../cases/compiler/metadataOfStringLiteral.ts | 8 ++++++ 4 files changed, 68 insertions(+) create mode 100644 tests/baselines/reference/metadataOfStringLiteral.js create mode 100644 tests/baselines/reference/metadataOfStringLiteral.symbols create mode 100644 tests/baselines/reference/metadataOfStringLiteral.types create mode 100644 tests/cases/compiler/metadataOfStringLiteral.ts diff --git a/tests/baselines/reference/metadataOfStringLiteral.js b/tests/baselines/reference/metadataOfStringLiteral.js new file mode 100644 index 0000000000000..bcfd2c334894e --- /dev/null +++ b/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", Object) +], Foo.prototype, "foo"); diff --git a/tests/baselines/reference/metadataOfStringLiteral.symbols b/tests/baselines/reference/metadataOfStringLiteral.symbols new file mode 100644 index 0000000000000..959a3403e1476 --- /dev/null +++ b/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)) +} diff --git a/tests/baselines/reference/metadataOfStringLiteral.types b/tests/baselines/reference/metadataOfStringLiteral.types new file mode 100644 index 0000000000000..666cdf38e459d --- /dev/null +++ b/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" +} diff --git a/tests/cases/compiler/metadataOfStringLiteral.ts b/tests/cases/compiler/metadataOfStringLiteral.ts new file mode 100644 index 0000000000000..d5ff9bcf22b45 --- /dev/null +++ b/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"; +} \ No newline at end of file From 40c2a5316406eb9309f4b55151c88d036e0d3c23 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 5 Oct 2016 11:24:26 -0700 Subject: [PATCH 2/4] For union or intersection types use constituent serialized type if its same for all of the constituent types Fixes #10809 --- src/compiler/transformers/ts.ts | 35 +++++++++++++++++-- .../reference/metadataOfStringLiteral.js | 2 +- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 9b36067f538b6..2419ffa4c3b73 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1801,10 +1801,41 @@ namespace ts { case SyntaxKind.TypeReference: return serializeTypeReferenceNode(node); + case SyntaxKind.IntersectionType: + case SyntaxKind.UnionType: + { + const unionOrIntersection = 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; diff --git a/tests/baselines/reference/metadataOfStringLiteral.js b/tests/baselines/reference/metadataOfStringLiteral.js index bcfd2c334894e..676914681cb91 100644 --- a/tests/baselines/reference/metadataOfStringLiteral.js +++ b/tests/baselines/reference/metadataOfStringLiteral.js @@ -24,5 +24,5 @@ var Foo = (function () { }()); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", String) ], Foo.prototype, "foo"); From 32de4d7f08a025b0e59b6a83a1cafc580ce9449e Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 5 Oct 2016 11:24:26 -0700 Subject: [PATCH 3/4] Another test case --- tests/baselines/reference/metadataOfUnion.js | 50 +++++++++++++++++++ .../reference/metadataOfUnion.symbols | 33 ++++++++++++ .../baselines/reference/metadataOfUnion.types | 34 +++++++++++++ tests/cases/compiler/metadataOfUnion.ts | 17 +++++++ 4 files changed, 134 insertions(+) create mode 100644 tests/baselines/reference/metadataOfUnion.js create mode 100644 tests/baselines/reference/metadataOfUnion.symbols create mode 100644 tests/baselines/reference/metadataOfUnion.types create mode 100644 tests/cases/compiler/metadataOfUnion.ts diff --git a/tests/baselines/reference/metadataOfUnion.js b/tests/baselines/reference/metadataOfUnion.js new file mode 100644 index 0000000000000..16d0e9c08b880 --- /dev/null +++ b/tests/baselines/reference/metadataOfUnion.js @@ -0,0 +1,50 @@ +//// [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; +} + +//// [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"); diff --git a/tests/baselines/reference/metadataOfUnion.symbols b/tests/baselines/reference/metadataOfUnion.symbols new file mode 100644 index 0000000000000..92934ad20250a --- /dev/null +++ b/tests/baselines/reference/metadataOfUnion.symbols @@ -0,0 +1,33 @@ +=== 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)) +} diff --git a/tests/baselines/reference/metadataOfUnion.types b/tests/baselines/reference/metadataOfUnion.types new file mode 100644 index 0000000000000..07a2724bd511a --- /dev/null +++ b/tests/baselines/reference/metadataOfUnion.types @@ -0,0 +1,34 @@ +=== 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" +} diff --git a/tests/cases/compiler/metadataOfUnion.ts b/tests/cases/compiler/metadataOfUnion.ts new file mode 100644 index 0000000000000..7676ea81e77d7 --- /dev/null +++ b/tests/cases/compiler/metadataOfUnion.ts @@ -0,0 +1,17 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +function PropDeco(target: Object, propKey: string | symbol) { } + +class A { +} + +class B { + @PropDeco + x: "foo" | A; + + @PropDeco + y: true | boolean; + + @PropDeco + z: "foo" | boolean; +} \ No newline at end of file From 8e4efb6cd96e272eac264950924b63d686ee60f2 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 5 Oct 2016 17:40:01 -0700 Subject: [PATCH 4/4] Added test case for enums --- tests/baselines/reference/metadataOfUnion.js | 49 +++++++++++++++++ .../reference/metadataOfUnion.symbols | 52 +++++++++++++++++++ .../baselines/reference/metadataOfUnion.types | 52 +++++++++++++++++++ tests/cases/compiler/metadataOfUnion.ts | 21 ++++++++ 4 files changed, 174 insertions(+) diff --git a/tests/baselines/reference/metadataOfUnion.js b/tests/baselines/reference/metadataOfUnion.js index 16d0e9c08b880..9a88481c80a9e 100644 --- a/tests/baselines/reference/metadataOfUnion.js +++ b/tests/baselines/reference/metadataOfUnion.js @@ -13,6 +13,27 @@ class B { @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] @@ -48,3 +69,31 @@ __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"); diff --git a/tests/baselines/reference/metadataOfUnion.symbols b/tests/baselines/reference/metadataOfUnion.symbols index 92934ad20250a..22c0cc3760229 100644 --- a/tests/baselines/reference/metadataOfUnion.symbols +++ b/tests/baselines/reference/metadataOfUnion.symbols @@ -31,3 +31,55 @@ class B { 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)) +} diff --git a/tests/baselines/reference/metadataOfUnion.types b/tests/baselines/reference/metadataOfUnion.types index 07a2724bd511a..08afc4e81bb43 100644 --- a/tests/baselines/reference/metadataOfUnion.types +++ b/tests/baselines/reference/metadataOfUnion.types @@ -32,3 +32,55 @@ class B { 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 +} diff --git a/tests/cases/compiler/metadataOfUnion.ts b/tests/cases/compiler/metadataOfUnion.ts index 7676ea81e77d7..2093357cb31e0 100644 --- a/tests/cases/compiler/metadataOfUnion.ts +++ b/tests/cases/compiler/metadataOfUnion.ts @@ -14,4 +14,25 @@ class B { @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; } \ No newline at end of file