diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index 6338dedc582..a313d72df85 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -3885,7 +3885,21 @@ func IsExpandoInitializer(initializer *Node) bool { } func GetContainingFunction(node *Node) *Node { - return FindAncestor(node.Parent, IsFunctionLike) + node = node.Parent + for node != nil { + if node.Kind == KindComputedPropertyName { + if node.Parent != nil && node.Parent.Parent != nil { + node = node.Parent.Parent + continue + } + return nil + } + if IsFunctionLike(node) { + return node + } + node = node.Parent + } + return nil } func IsImplicitlyExportedJSTypeAlias(node *Node) bool { diff --git a/internal/checker/utilities.go b/internal/checker/utilities.go index 6fdedd0a912..d58c0b8c492 100644 --- a/internal/checker/utilities.go +++ b/internal/checker/utilities.go @@ -816,7 +816,21 @@ func (s *orderedSet[T]) add(value T) { } func getContainingFunctionOrClassStaticBlock(node *ast.Node) *ast.Node { - return ast.FindAncestor(node.Parent, ast.IsFunctionLikeOrClassStaticBlockDeclaration) + node = node.Parent + for node != nil { + if node.Kind == ast.KindComputedPropertyName { + if node.Parent != nil && node.Parent.Parent != nil { + node = node.Parent.Parent + continue + } + return nil + } + if ast.IsFunctionLikeOrClassStaticBlockDeclaration(node) { + return node + } + node = node.Parent + } + return nil } func isNodeDescendantOf(node *ast.Node, ancestor *ast.Node) bool { diff --git a/testdata/baselines/reference/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.errors.txt b/testdata/baselines/reference/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.errors.txt new file mode 100644 index 00000000000..46113a10d1d --- /dev/null +++ b/testdata/baselines/reference/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.errors.txt @@ -0,0 +1,14 @@ +yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts(5,7): error TS7057: 'yield' expression implicitly results in an 'any' type because its containing generator lacks a return-type annotation. + + +==== yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts (1 errors) ==== + // https://github.com/microsoft/TypeScript/issues/62941 + + function* g() { + let x: any = { + *[yield 0]() {}, + ~~~~~ +!!! error TS7057: 'yield' expression implicitly results in an 'any' type because its containing generator lacks a return-type annotation. + }; + } + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.symbols b/testdata/baselines/reference/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.symbols new file mode 100644 index 00000000000..4e406efe098 --- /dev/null +++ b/testdata/baselines/reference/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.symbols @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts] //// + +=== yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts === +// https://github.com/microsoft/TypeScript/issues/62941 + +function* g() { +>g : Symbol(g, Decl(yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts, 0, 0)) + + let x: any = { +>x : Symbol(x, Decl(yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts, 3, 5)) + + *[yield 0]() {}, +>[yield 0] : Symbol([yield 0], Decl(yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts, 3, 16)) + + }; +} + diff --git a/testdata/baselines/reference/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.types b/testdata/baselines/reference/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.types new file mode 100644 index 00000000000..0347c10be22 --- /dev/null +++ b/testdata/baselines/reference/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.types @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts] //// + +=== yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts === +// https://github.com/microsoft/TypeScript/issues/62941 + +function* g() { +>g : () => Generator + + let x: any = { +>x : any +>{ *[yield 0]() {}, } : { [x: number]: () => Generator; } + + *[yield 0]() {}, +>[yield 0] : () => Generator +>yield 0 : any +>0 : 0 + + }; +} + diff --git a/testdata/baselines/reference/conformance/classStaticBlock29.errors.txt b/testdata/baselines/reference/conformance/classStaticBlock29.errors.txt new file mode 100644 index 00000000000..2932f2f593e --- /dev/null +++ b/testdata/baselines/reference/conformance/classStaticBlock29.errors.txt @@ -0,0 +1,20 @@ +classStaticBlock29.ts(3,19): error TS18037: 'await' expression cannot be used inside a class static block. +classStaticBlock29.ts(4,19): error TS18037: 'await' expression cannot be used inside a class static block. +classStaticBlock29.ts(5,23): error TS18037: 'await' expression cannot be used inside a class static block. + + +==== classStaticBlock29.ts (3 errors) ==== + class C { + static { + const o1 = { [await 1]: '' }; + ~~~~~~~ +!!! error TS18037: 'await' expression cannot be used inside a class static block. + const o2 = { [await 1]() { return ''; } }; + ~~~~~~~ +!!! error TS18037: 'await' expression cannot be used inside a class static block. + const o3 = { get [await 1]() { return ''; } }; + ~~~~~~~ +!!! error TS18037: 'await' expression cannot be used inside a class static block. + } + } + \ No newline at end of file diff --git a/testdata/baselines/reference/conformance/classStaticBlock29.symbols b/testdata/baselines/reference/conformance/classStaticBlock29.symbols new file mode 100644 index 00000000000..94892fe8e01 --- /dev/null +++ b/testdata/baselines/reference/conformance/classStaticBlock29.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/classes/classStaticBlock/classStaticBlock29.ts] //// + +=== classStaticBlock29.ts === +class C { +>C : Symbol(C, Decl(classStaticBlock29.ts, 0, 0)) + + static { + const o1 = { [await 1]: '' }; +>o1 : Symbol(o1, Decl(classStaticBlock29.ts, 2, 9)) +>[await 1] : Symbol([await 1], Decl(classStaticBlock29.ts, 2, 16)) + + const o2 = { [await 1]() { return ''; } }; +>o2 : Symbol(o2, Decl(classStaticBlock29.ts, 3, 9)) +>[await 1] : Symbol([await 1], Decl(classStaticBlock29.ts, 3, 16)) + + const o3 = { get [await 1]() { return ''; } }; +>o3 : Symbol(o3, Decl(classStaticBlock29.ts, 4, 9)) +>[await 1] : Symbol([await 1], Decl(classStaticBlock29.ts, 4, 16)) + } +} + diff --git a/testdata/baselines/reference/conformance/classStaticBlock29.types b/testdata/baselines/reference/conformance/classStaticBlock29.types new file mode 100644 index 00000000000..fdcf17f98c2 --- /dev/null +++ b/testdata/baselines/reference/conformance/classStaticBlock29.types @@ -0,0 +1,33 @@ +//// [tests/cases/conformance/classes/classStaticBlock/classStaticBlock29.ts] //// + +=== classStaticBlock29.ts === +class C { +>C : C + + static { + const o1 = { [await 1]: '' }; +>o1 : { 1: string; } +>{ [await 1]: '' } : { 1: string; } +>[await 1] : string +>await 1 : 1 +>1 : 1 +>'' : "" + + const o2 = { [await 1]() { return ''; } }; +>o2 : { 1(): string; } +>{ [await 1]() { return ''; } } : { 1(): string; } +>[await 1] : () => string +>await 1 : 1 +>1 : 1 +>'' : "" + + const o3 = { get [await 1]() { return ''; } }; +>o3 : {} +>{ get [await 1]() { return ''; } } : {} +>[await 1] : string +>await 1 : 1 +>1 : 1 +>'' : "" + } +} + diff --git a/testdata/tests/cases/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts b/testdata/tests/cases/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts new file mode 100644 index 00000000000..081cebcab3d --- /dev/null +++ b/testdata/tests/cases/compiler/yieldInComputedNameOfContextuallyTypedObjectNoCrash1.ts @@ -0,0 +1,11 @@ +// @strict: true +// @target: esnext +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/62941 + +function* g() { + let x: any = { + *[yield 0]() {}, + }; +} diff --git a/testdata/tests/cases/conformance/classes/classStaticBlock/classStaticBlock29.ts b/testdata/tests/cases/conformance/classes/classStaticBlock/classStaticBlock29.ts new file mode 100644 index 00000000000..5a086ffbe53 --- /dev/null +++ b/testdata/tests/cases/conformance/classes/classStaticBlock/classStaticBlock29.ts @@ -0,0 +1,11 @@ +// @strict: true +// @target: esnext +// @noEmit: true + +class C { + static { + const o1 = { [await 1]: '' }; + const o2 = { [await 1]() { return ''; } }; + const o3 = { get [await 1]() { return ''; } }; + } +}