Skip to content
Open
2 changes: 1 addition & 1 deletion internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -1748,7 +1748,7 @@ func (p *Parser) parseClassDeclarationOrExpression(pos int, jsdoc jsdocScannerIn
// We don't parse the name here in await context, instead we will report a grammar error in the checker.
name := p.parseNameOfClassDeclarationOrExpression()
typeParameters := p.parseTypeParameters()
if modifiers != nil && core.Some(modifiers.Nodes, isExportModifier) {
if modifiers != nil && p.parsingContexts == 1<<PCSourceElements && core.Some(modifiers.Nodes, isExportModifier) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Equals? Not AND?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's a good way to demonstrate this is wrong?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, Copilot, figure out where this would matter and add a testcase

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added regression coverage in de9f3d2 to demonstrate where this matters, including nested namespace export class cases and static computed members in both allowed/disallowed await contexts.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Knew it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, it didn't change it away from an ==? I hate when it says "added whatever to demonstrate it matters" and then doesn't at all explain why it matters or why I'm wrong

Indistuiguishable from a slop PR author at that point 😛

p.setContextFlags(ast.NodeFlagsAwaitContext, true /*value*/)
}
heritageClauses := p.parseHeritageClauses()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
awaitInNamespaceExportedClassComputedProperty.ts(3,16): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
awaitInNamespaceExportedClassComputedProperty.ts(4,23): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
awaitInNamespaceExportedClassComputedProperty.ts(13,16): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
awaitInNamespaceExportedClassComputedProperty.ts(21,16): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
awaitInNamespaceExportedClassComputedProperty.ts(31,24): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.


==== awaitInNamespaceExportedClassComputedProperty.ts (5 errors) ====
declare const x: string;
namespace N {
class A { [await x]() {} }
~~~~~
!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
!!! related TS1356 awaitInNamespaceExportedClassComputedProperty.ts:3:15: Did you mean to mark this function as 'async'?
export class B { [await x]() {} }
~~~~~
!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
!!! related TS1356 awaitInNamespaceExportedClassComputedProperty.ts:4:22: Did you mean to mark this function as 'async'?
}
export class C { [await x]() {} }

{
class D { [await x]() {} }
}

function f() {
class E { [await x]() {} }
~~~~~
!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
!!! related TS1356 awaitInNamespaceExportedClassComputedProperty.ts:13:15: Did you mean to mark this function as 'async'?
}

async function af() {
class F { [await x]() {} }
}

function* gf() {
class G { [await x]() {} }
~~~~~
!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
!!! related TS1356 awaitInNamespaceExportedClassComputedProperty.ts:21:15: Did you mean to mark this function as 'async'?
}

async function* agf() {
class H { [await x]() {} }
}

function switchSync() {
switch (0) {
case 0:
class I { [await x]() {} }
~~~~~
!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
!!! related TS1356 awaitInNamespaceExportedClassComputedProperty.ts:31:23: Did you mean to mark this function as 'async'?
}
}

async function switchAsync() {
switch (0) {
case 0:
class J { [await x]() {} }
}
}

export {};

Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//// [tests/cases/compiler/awaitInNamespaceExportedClassComputedProperty.ts] ////

//// [awaitInNamespaceExportedClassComputedProperty.ts]
declare const x: string;
namespace N {
class A { [await x]() {} }
export class B { [await x]() {} }
}
export class C { [await x]() {} }

{
class D { [await x]() {} }
}

function f() {
class E { [await x]() {} }
}

async function af() {
class F { [await x]() {} }
}

function* gf() {
class G { [await x]() {} }
}

async function* agf() {
class H { [await x]() {} }
}

function switchSync() {
switch (0) {
case 0:
class I { [await x]() {} }
}
}

async function switchAsync() {
switch (0) {
case 0:
class J { [await x]() {} }
}
}

export {};


//// [awaitInNamespaceExportedClassComputedProperty.js]
var N;
(function (N) {
class A {
[await x]() { }
}
class B {
[await x]() { }
}
N.B = B;
})(N || (N = {}));
export class C {
[await x]() { }
}
{
class D {
[await x]() { }
}
}
function f() {
class E {
[await x]() { }
}
}
async function af() {
class F {
[await x]() { }
}
}
function* gf() {
class G {
[await x]() { }
}
}
async function* agf() {
class H {
[await x]() { }
}
}
function switchSync() {
switch (0) {
case 0:
class I {
[await x]() { }
}
}
}
async function switchAsync() {
switch (0) {
case 0:
class J {
[await x]() { }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//// [tests/cases/compiler/awaitInNamespaceExportedClassComputedProperty.ts] ////

=== awaitInNamespaceExportedClassComputedProperty.ts ===
declare const x: string;
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))

namespace N {
>N : Symbol(N, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 24))

class A { [await x]() {} }
>A : Symbol(A, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 1, 13))
>[await x] : Symbol(A[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 2, 13))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))

export class B { [await x]() {} }
>B : Symbol(B, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 2, 30))
>[await x] : Symbol(B[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 3, 20))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))
}
export class C { [await x]() {} }
>C : Symbol(C, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 4, 1))
>[await x] : Symbol(C[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 5, 16))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))

{
class D { [await x]() {} }
>D : Symbol(D, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 7, 1))
>[await x] : Symbol(D[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 8, 13))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))
}

function f() {
>f : Symbol(f, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 9, 1))

class E { [await x]() {} }
>E : Symbol(E, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 11, 14))
>[await x] : Symbol(E[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 12, 13))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))
}

async function af() {
>af : Symbol(af, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 13, 1))

class F { [await x]() {} }
>F : Symbol(F, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 15, 21))
>[await x] : Symbol(F[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 16, 13))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))
}

function* gf() {
>gf : Symbol(gf, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 17, 1))

class G { [await x]() {} }
>G : Symbol(G, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 19, 16))
>[await x] : Symbol(G[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 20, 13))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))
}

async function* agf() {
>agf : Symbol(agf, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 21, 1))

class H { [await x]() {} }
>H : Symbol(H, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 23, 23))
>[await x] : Symbol(H[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 24, 13))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))
}

function switchSync() {
>switchSync : Symbol(switchSync, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 25, 1))

switch (0) {
case 0:
class I { [await x]() {} }
>I : Symbol(I, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 29, 15))
>[await x] : Symbol(I[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 30, 21))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))
}
}

async function switchAsync() {
>switchAsync : Symbol(switchAsync, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 32, 1))

switch (0) {
case 0:
class J { [await x]() {} }
>J : Symbol(J, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 36, 15))
>[await x] : Symbol(J[await x], Decl(awaitInNamespaceExportedClassComputedProperty.ts, 37, 21))
>x : Symbol(x, Decl(awaitInNamespaceExportedClassComputedProperty.ts, 0, 13))
}
}

export {};

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//// [tests/cases/compiler/awaitInNamespaceExportedClassComputedProperty.ts] ////

=== awaitInNamespaceExportedClassComputedProperty.ts ===
declare const x: string;
>x : string

namespace N {
>N : typeof N

class A { [await x]() {} }
>A : A
>[await x] : () => void
>await x : string
>x : string

export class B { [await x]() {} }
>B : B
>[await x] : () => void
>await x : string
>x : string
}
export class C { [await x]() {} }
>C : C
>[await x] : () => void
>await x : string
>x : string

{
class D { [await x]() {} }
>D : D
>[await x] : () => void
>await x : string
>x : string
}

function f() {
>f : () => void

class E { [await x]() {} }
>E : E
>[await x] : () => void
>await x : string
>x : string
}

async function af() {
>af : () => Promise<void>

class F { [await x]() {} }
>F : F
>[await x] : () => void
>await x : string
>x : string
}

function* gf() {
>gf : () => Generator<never, void, unknown>

class G { [await x]() {} }
>G : G
>[await x] : () => void
>await x : string
>x : string
}

async function* agf() {
>agf : () => AsyncGenerator<never, void, unknown>

class H { [await x]() {} }
>H : H
>[await x] : () => void
>await x : string
>x : string
}

function switchSync() {
>switchSync : () => void

switch (0) {
>0 : 0

case 0:
>0 : 0

class I { [await x]() {} }
>I : I
>[await x] : () => void
>await x : string
>x : string
}
}

async function switchAsync() {
>switchAsync : () => Promise<void>

switch (0) {
>0 : 0

case 0:
>0 : 0

class J { [await x]() {} }
>J : J
>[await x] : () => void
>await x : string
>x : string
}
}

export {};

Loading