Skip to content

Commit c33df01

Browse files
author
Andy
authored
Merge pull request microsoft#9156 from Microsoft/decorator_metadata_async
Emit 'Promise' decorator metadata return type for async methods
2 parents 29b1e79 + 33e4c7a commit c33df01

File tree

5 files changed

+149
-3
lines changed

5 files changed

+149
-3
lines changed

src/compiler/emitter.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6156,9 +6156,15 @@ const _super = (function (geti, seti) {
61566156

61576157
/** Serializes the return type of function. Used by the __metadata decorator for a method. */
61586158
function emitSerializedReturnTypeOfNode(node: Node) {
6159-
if (node && isFunctionLike(node) && (<FunctionLikeDeclaration>node).type) {
6160-
emitSerializedTypeNode((<FunctionLikeDeclaration>node).type);
6161-
return;
6159+
if (node && isFunctionLike(node)) {
6160+
if ((<FunctionLikeDeclaration>node).type) {
6161+
emitSerializedTypeNode((<FunctionLikeDeclaration>node).type);
6162+
return;
6163+
}
6164+
else if (isAsyncFunctionLike(<FunctionLikeDeclaration>node)) {
6165+
write("Promise");
6166+
return;
6167+
}
61626168
}
61636169

61646170
write("void 0");
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//// [decoratorMetadataPromise.ts]
2+
3+
declare const decorator: MethodDecorator;
4+
5+
class A {
6+
@decorator
7+
async foo() {}
8+
@decorator
9+
async bar(): Promise<number> { return 0; }
10+
@decorator
11+
baz(n: Promise<number>): Promise<number> { return n; }
12+
}
13+
14+
15+
//// [decoratorMetadataPromise.js]
16+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
17+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
18+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
19+
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;
20+
return c > 3 && r && Object.defineProperty(target, key, r), r;
21+
};
22+
var __metadata = (this && this.__metadata) || function (k, v) {
23+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
24+
};
25+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26+
return new (P || (P = Promise))(function (resolve, reject) {
27+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
28+
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
29+
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
30+
step((generator = generator.apply(thisArg, _arguments)).next());
31+
});
32+
};
33+
class A {
34+
foo() {
35+
return __awaiter(this, void 0, void 0, function* () { });
36+
}
37+
bar() {
38+
return __awaiter(this, void 0, void 0, function* () { return 0; });
39+
}
40+
baz(n) { return n; }
41+
}
42+
__decorate([
43+
decorator,
44+
__metadata('design:type', Function),
45+
__metadata('design:paramtypes', []),
46+
__metadata('design:returntype', Promise)
47+
], A.prototype, "foo", null);
48+
__decorate([
49+
decorator,
50+
__metadata('design:type', Function),
51+
__metadata('design:paramtypes', []),
52+
__metadata('design:returntype', Promise)
53+
], A.prototype, "bar", null);
54+
__decorate([
55+
decorator,
56+
__metadata('design:type', Function),
57+
__metadata('design:paramtypes', [Promise]),
58+
__metadata('design:returntype', Promise)
59+
], A.prototype, "baz", null);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/compiler/decoratorMetadataPromise.ts ===
2+
3+
declare const decorator: MethodDecorator;
4+
>decorator : Symbol(decorator, Decl(decoratorMetadataPromise.ts, 1, 13))
5+
>MethodDecorator : Symbol(MethodDecorator, Decl(lib.es5.d.ts, --, --))
6+
7+
class A {
8+
>A : Symbol(A, Decl(decoratorMetadataPromise.ts, 1, 41))
9+
10+
@decorator
11+
>decorator : Symbol(decorator, Decl(decoratorMetadataPromise.ts, 1, 13))
12+
13+
async foo() {}
14+
>foo : Symbol(A.foo, Decl(decoratorMetadataPromise.ts, 3, 9))
15+
16+
@decorator
17+
>decorator : Symbol(decorator, Decl(decoratorMetadataPromise.ts, 1, 13))
18+
19+
async bar(): Promise<number> { return 0; }
20+
>bar : Symbol(A.bar, Decl(decoratorMetadataPromise.ts, 5, 18))
21+
>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --))
22+
23+
@decorator
24+
>decorator : Symbol(decorator, Decl(decoratorMetadataPromise.ts, 1, 13))
25+
26+
baz(n: Promise<number>): Promise<number> { return n; }
27+
>baz : Symbol(A.baz, Decl(decoratorMetadataPromise.ts, 7, 46))
28+
>n : Symbol(n, Decl(decoratorMetadataPromise.ts, 9, 8))
29+
>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --))
30+
>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --))
31+
>n : Symbol(n, Decl(decoratorMetadataPromise.ts, 9, 8))
32+
}
33+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/compiler/decoratorMetadataPromise.ts ===
2+
3+
declare const decorator: MethodDecorator;
4+
>decorator : <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void
5+
>MethodDecorator : <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void
6+
7+
class A {
8+
>A : A
9+
10+
@decorator
11+
>decorator : <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void
12+
13+
async foo() {}
14+
>foo : () => Promise<void>
15+
16+
@decorator
17+
>decorator : <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void
18+
19+
async bar(): Promise<number> { return 0; }
20+
>bar : () => Promise<number>
21+
>Promise : Promise<T>
22+
>0 : number
23+
24+
@decorator
25+
>decorator : <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void
26+
27+
baz(n: Promise<number>): Promise<number> { return n; }
28+
>baz : (n: Promise<number>) => Promise<number>
29+
>n : Promise<number>
30+
>Promise : Promise<T>
31+
>Promise : Promise<T>
32+
>n : Promise<number>
33+
}
34+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @experimentaldecorators: true
2+
// @emitdecoratormetadata: true
3+
// @target: es6
4+
5+
declare const decorator: MethodDecorator;
6+
7+
class A {
8+
@decorator
9+
async foo() {}
10+
@decorator
11+
async bar(): Promise<number> { return 0; }
12+
@decorator
13+
baz(n: Promise<number>): Promise<number> { return n; }
14+
}

0 commit comments

Comments
 (0)