Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13676,7 +13676,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
&& !getContainingClassStaticBlock(derived.valueDeclaration)
) {
symbols.set(base.escapedName, base);
Copy link
Member

Choose a reason for hiding this comment

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

Is this drive-by, or necessary?

symbols.set(base.escapedName, base);
}
}
}
Expand Down
52 changes: 43 additions & 9 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3078,12 +3078,30 @@ export function forEachTsConfigPropArray<T>(tsConfigSourceFile: TsConfigSourceFi

/** @internal */
export function getContainingFunction(node: Node): SignatureDeclaration | undefined {
return findAncestor(node.parent, isFunctionLike);
while (node = node.parent) {
if (node.kind === SyntaxKind.ComputedPropertyName) {
node = node.parent.parent;
continue;
}
if (isFunctionLike(node)) {
return node;
}
}
return undefined;
}

/** @internal */
export function getContainingFunctionDeclaration(node: Node): FunctionLikeDeclaration | undefined {
return findAncestor(node.parent, isFunctionLikeDeclaration);
export function getContainingFunctionDeclaration(node: Node, includeComputedPropertyName: boolean): FunctionLikeDeclaration | undefined {
while (node = node.parent) {
if (!includeComputedPropertyName && node.kind === SyntaxKind.ComputedPropertyName) {
node = node.parent.parent;
continue;
}
if (isFunctionLikeDeclaration(node)) {
return node;
}
}
return undefined;
}

/** @internal */
Expand All @@ -3093,17 +3111,33 @@ export function getContainingClass(node: Node): ClassLikeDeclaration | undefined

/** @internal */
export function getContainingClassStaticBlock(node: Node): Node | undefined {
return findAncestor(node.parent, n => {
if (isClassLike(n) || isFunctionLike(n)) {
return "quit";
while (node = node.parent) {
if (node.kind === SyntaxKind.ComputedPropertyName) {
node = node.parent.parent;
continue;
}
return isClassStaticBlockDeclaration(n);
});
if (isClassLike(node) || isFunctionLike(node)) {
return undefined;
}
if (isClassStaticBlockDeclaration(node)) {
return node;
}
}
return undefined;
}

/** @internal */
export function getContainingFunctionOrClassStaticBlock(node: Node): SignatureDeclaration | ClassStaticBlockDeclaration | undefined {
return findAncestor(node.parent, isFunctionLikeOrClassStaticBlockDeclaration);
while (node = node.parent) {
if (node.kind === SyntaxKind.ComputedPropertyName) {
node = node.parent.parent;
continue;
}
if (isFunctionLikeOrClassStaticBlockDeclaration(node)) {
return node;
}
}
return undefined;
}

/** @internal */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ function entryToType(entry: FindAllReferences.NodeEntry): Node | undefined {

function getFunctionDeclarationAtPosition(file: SourceFile, startPosition: number, checker: TypeChecker): ValidFunctionDeclaration | undefined {
const node = getTouchingToken(file, startPosition);
const functionDeclaration = getContainingFunctionDeclaration(node);
const functionDeclaration = getContainingFunctionDeclaration(node, /*includeComputedPropertyName*/ true);

// don't offer refactor on top-level JSDoc
if (isTopLevelJSDoc(node)) return undefined;
Expand Down
20 changes: 20 additions & 0 deletions tests/baselines/reference/classStaticBlock29.errors.txt
Original file line number Diff line number Diff line change
@@ -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.
}
}

21 changes: 21 additions & 0 deletions tests/baselines/reference/classStaticBlock29.symbols
Original file line number Diff line number Diff line change
@@ -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))
}
}

52 changes: 52 additions & 0 deletions tests/baselines/reference/classStaticBlock29.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//// [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
> : ^
>'' : ""
> : ^^
}
}

44 changes: 44 additions & 0 deletions tests/baselines/reference/staticPropertyAssignmentInherited1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//// [tests/cases/conformance/salsa/staticPropertyAssignmentInherited1.ts] ////

//// [staticPropertyAssignmentInherited1.js]
let v = Math.random() ? '' : Math.random() ? 0 : undefined;

class Base {
static value1 = v;
static value2 = v;
static value3 = v;
}

class Derived extends Base {
static {
this.value1 = 10;
this.value4 = {
[this.value2 = 20]: ''
}
this.value5 = {
get [this.value3 = 30]() { return ''; }
}
}
}

/** @param {typeof Derived} cls */
function test(cls) {
cls.value1;
cls.value2;
cls.value3;
}




//// [staticPropertyAssignmentInherited1.d.ts]
/** @param {typeof Derived} cls */
declare function test(cls: typeof Derived): void;
declare let v: string | number | undefined;
declare class Base {
static value1: string | number | undefined;
static value2: string | number | undefined;
static value3: string | number | undefined;
}
declare class Derived extends Base {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//// [tests/cases/conformance/salsa/staticPropertyAssignmentInherited1.ts] ////

=== staticPropertyAssignmentInherited1.js ===
let v = Math.random() ? '' : Math.random() ? 0 : undefined;
>v : Symbol(v, Decl(staticPropertyAssignmentInherited1.js, 0, 3))
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>undefined : Symbol(undefined)

class Base {
>Base : Symbol(Base, Decl(staticPropertyAssignmentInherited1.js, 0, 59))

static value1 = v;
>value1 : Symbol(Base.value1, Decl(staticPropertyAssignmentInherited1.js, 2, 12))
>v : Symbol(v, Decl(staticPropertyAssignmentInherited1.js, 0, 3))

static value2 = v;
>value2 : Symbol(Base.value2, Decl(staticPropertyAssignmentInherited1.js, 3, 20))
>v : Symbol(v, Decl(staticPropertyAssignmentInherited1.js, 0, 3))

static value3 = v;
>value3 : Symbol(Base.value3, Decl(staticPropertyAssignmentInherited1.js, 4, 20))
>v : Symbol(v, Decl(staticPropertyAssignmentInherited1.js, 0, 3))
}

class Derived extends Base {
>Derived : Symbol(Derived, Decl(staticPropertyAssignmentInherited1.js, 6, 1))
>Base : Symbol(Base, Decl(staticPropertyAssignmentInherited1.js, 0, 59))

static {
this.value1 = 10;
>this.value1 : Symbol(Derived.value1, Decl(staticPropertyAssignmentInherited1.js, 9, 10))
>this : Symbol(Derived, Decl(staticPropertyAssignmentInherited1.js, 6, 1))
>value1 : Symbol(Derived.value1, Decl(staticPropertyAssignmentInherited1.js, 9, 10))

this.value4 = {
>this.value4 : Symbol(Derived.value4, Decl(staticPropertyAssignmentInherited1.js, 10, 21))
>this : Symbol(Derived, Decl(staticPropertyAssignmentInherited1.js, 6, 1))
>value4 : Symbol(Derived.value4, Decl(staticPropertyAssignmentInherited1.js, 10, 21))

[this.value2 = 20]: ''
>[this.value2 = 20] : Symbol([this.value2 = 20], Decl(staticPropertyAssignmentInherited1.js, 11, 19))
>this.value2 : Symbol(Derived.value2, Decl(staticPropertyAssignmentInherited1.js, 12, 7))
>this : Symbol(Derived, Decl(staticPropertyAssignmentInherited1.js, 6, 1))
>value2 : Symbol(Derived.value2, Decl(staticPropertyAssignmentInherited1.js, 12, 7))
}
this.value5 = {
>this.value5 : Symbol(Derived.value5, Decl(staticPropertyAssignmentInherited1.js, 13, 5))
>this : Symbol(Derived, Decl(staticPropertyAssignmentInherited1.js, 6, 1))
>value5 : Symbol(Derived.value5, Decl(staticPropertyAssignmentInherited1.js, 13, 5))

get [this.value3 = 30]() { return ''; }
>[this.value3 = 30] : Symbol([this.value3 = 30], Decl(staticPropertyAssignmentInherited1.js, 14, 19))
>this.value3 : Symbol(Derived.value3, Decl(staticPropertyAssignmentInherited1.js, 15, 11))
>this : Symbol(Derived, Decl(staticPropertyAssignmentInherited1.js, 6, 1))
>value3 : Symbol(Derived.value3, Decl(staticPropertyAssignmentInherited1.js, 15, 11))
}
}
}

/** @param {typeof Derived} cls */
function test(cls) {
>test : Symbol(test, Decl(staticPropertyAssignmentInherited1.js, 18, 1))
>cls : Symbol(cls, Decl(staticPropertyAssignmentInherited1.js, 21, 14))

cls.value1;
>cls.value1 : Symbol(Derived.value1, Decl(staticPropertyAssignmentInherited1.js, 9, 10))
>cls : Symbol(cls, Decl(staticPropertyAssignmentInherited1.js, 21, 14))
>value1 : Symbol(Derived.value1, Decl(staticPropertyAssignmentInherited1.js, 9, 10))

cls.value2;
>cls.value2 : Symbol(Derived.value2, Decl(staticPropertyAssignmentInherited1.js, 12, 7))
>cls : Symbol(cls, Decl(staticPropertyAssignmentInherited1.js, 21, 14))
>value2 : Symbol(Derived.value2, Decl(staticPropertyAssignmentInherited1.js, 12, 7))

cls.value3;
>cls.value3 : Symbol(Derived.value3, Decl(staticPropertyAssignmentInherited1.js, 15, 11))
>cls : Symbol(cls, Decl(staticPropertyAssignmentInherited1.js, 21, 14))
>value3 : Symbol(Derived.value3, Decl(staticPropertyAssignmentInherited1.js, 15, 11))
}

Loading