Skip to content

Commit

Permalink
Parse parameter decorators outside of Await context when appropriate (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuckton committed Jul 25, 2022
1 parent a179e91 commit 12dbdf0
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3337,7 +3337,7 @@ namespace ts {
// BindingElement[?Yield,?Await]

// Decorators are parsed in the outer [Await] context, the rest of the parameter is parsed in the function's [Await] context.
const decorators = inOuterAwaitContext ? doInAwaitContext(parseDecorators) : parseDecorators();
const decorators = inOuterAwaitContext ? doInAwaitContext(parseDecorators) : doOutsideOfAwaitContext(parseDecorators);

if (token() === SyntaxKind.ThisKeyword) {
const node = factory.createParameterDeclaration(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter3.ts(5,23): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.


==== tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter3.ts (1 errors) ====
// https://github.com/microsoft/TypeScript/issues/48509
declare function dec(a: any): any;
function fn(value: Promise<number>): any {
class Class {
async method(@dec(await value) arg: number) {}
~~~~~
!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
}
return Class
}

41 changes: 41 additions & 0 deletions tests/baselines/reference/decoratorOnClassMethodParameter3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//// [decoratorOnClassMethodParameter3.ts]
// https://github.com/microsoft/TypeScript/issues/48509
declare function dec(a: any): any;
function fn(value: Promise<number>): any {
class Class {
async method(@dec(await value) arg: number) {}
}
return Class
}


//// [decoratorOnClassMethodParameter3.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 __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
function fn(value) {
class Class {
method(arg) {
return __awaiter(this, void 0, void 0, function* () { });
}
}
__decorate([
__param(0, dec(yield value))
], Class.prototype, "method", null);
return Class;
}
24 changes: 24 additions & 0 deletions tests/baselines/reference/decoratorOnClassMethodParameter3.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
=== tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter3.ts ===
// https://github.com/microsoft/TypeScript/issues/48509
declare function dec(a: any): any;
>dec : Symbol(dec, Decl(decoratorOnClassMethodParameter3.ts, 0, 0))
>a : Symbol(a, Decl(decoratorOnClassMethodParameter3.ts, 1, 21))

function fn(value: Promise<number>): any {
>fn : Symbol(fn, Decl(decoratorOnClassMethodParameter3.ts, 1, 34))
>value : Symbol(value, Decl(decoratorOnClassMethodParameter3.ts, 2, 12))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))

class Class {
>Class : Symbol(Class, Decl(decoratorOnClassMethodParameter3.ts, 2, 42))

async method(@dec(await value) arg: number) {}
>method : Symbol(Class.method, Decl(decoratorOnClassMethodParameter3.ts, 3, 15))
>dec : Symbol(dec, Decl(decoratorOnClassMethodParameter3.ts, 0, 0))
>value : Symbol(value, Decl(decoratorOnClassMethodParameter3.ts, 2, 12))
>arg : Symbol(arg, Decl(decoratorOnClassMethodParameter3.ts, 4, 17))
}
return Class
>Class : Symbol(Class, Decl(decoratorOnClassMethodParameter3.ts, 2, 42))
}

25 changes: 25 additions & 0 deletions tests/baselines/reference/decoratorOnClassMethodParameter3.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
=== tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter3.ts ===
// https://github.com/microsoft/TypeScript/issues/48509
declare function dec(a: any): any;
>dec : (a: any) => any
>a : any

function fn(value: Promise<number>): any {
>fn : (value: Promise<number>) => any
>value : Promise<number>

class Class {
>Class : Class

async method(@dec(await value) arg: number) {}
>method : (arg: number) => Promise<void>
>dec(await value) : any
>dec : (a: any) => any
>await value : number
>value : Promise<number>
>arg : number
}
return Class
>Class : typeof Class
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @target: es2015
// @experimentaldecorators: true

// https://github.com/microsoft/TypeScript/issues/48509
declare function dec(a: any): any;
function fn(value: Promise<number>): any {
class Class {
async method(@dec(await value) arg: number) {}
}
return Class
}

0 comments on commit 12dbdf0

Please sign in to comment.