Skip to content

Commit

Permalink
Cache started nonexistent property error checks to prevent reentrancy…
Browse files Browse the repository at this point in the history
… in the check (#60683)
  • Loading branch information
weswigham authored Dec 4, 2024
1 parent 4105134 commit 517da72
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34466,6 +34466,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function reportNonexistentProperty(propNode: Identifier | PrivateIdentifier, containingType: Type, isUncheckedJS: boolean) {
const links = getNodeLinks(propNode);
const cache = (links.nonExistentPropCheckCache ||= new Set());
const key = `${getTypeId(containingType)}|${isUncheckedJS}`;
if (cache.has(key)) {
return;
}
cache.add(key);
let errorInfo: DiagnosticMessageChain | undefined;
let relatedInfo: Diagnostic | undefined;
if (!isPrivateIdentifier(propNode) && containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) {
Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6254,6 +6254,7 @@ export interface NodeLinks {
potentialUnusedRenamedBindingElementsInTypes?: BindingElement[];
externalHelpersModule?: Symbol; // Resolved symbol for the external helpers module
instantiationExpressionTypes?: Map<number, Type>; // Cache of instantiation expression types for the node
nonExistentPropCheckCache?: Set<string>;
}

/** @internal */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
checkingObjectWithThisInNamePositionNoCrash.ts(2,5): error TS7023: 'doit' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
checkingObjectWithThisInNamePositionNoCrash.ts(4,19): error TS2339: Property 'a' does not exist on type '{ doit(): { [x: number]: string; }; }'.


==== checkingObjectWithThisInNamePositionNoCrash.ts (2 errors) ====
export const thing = {
doit() {
~~~~
!!! error TS7023: 'doit' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
return {
[this.a]: "", // should refer to the outer object with the doit method, notably not present
~
!!! error TS2339: Property 'a' does not exist on type '{ doit(): { [x: number]: string; }; }'.
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//// [tests/cases/compiler/checkingObjectWithThisInNamePositionNoCrash.ts] ////

//// [checkingObjectWithThisInNamePositionNoCrash.ts]
export const thing = {
doit() {
return {
[this.a]: "", // should refer to the outer object with the doit method, notably not present
}
}
}

//// [checkingObjectWithThisInNamePositionNoCrash.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.thing = void 0;
exports.thing = {
doit: function () {
var _a;
return _a = {},
_a[this.a] = "",
_a;
}
};


//// [checkingObjectWithThisInNamePositionNoCrash.d.ts]
export declare const thing: {
doit(): {
[x: number]: string;
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//// [tests/cases/compiler/checkingObjectWithThisInNamePositionNoCrash.ts] ////

=== checkingObjectWithThisInNamePositionNoCrash.ts ===
export const thing = {
>thing : Symbol(thing, Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 0, 12))

doit() {
>doit : Symbol(doit, Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 0, 22))

return {
[this.a]: "", // should refer to the outer object with the doit method, notably not present
>[this.a] : Symbol([this.a], Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 2, 16))
>this : Symbol(thing, Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 0, 20))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//// [tests/cases/compiler/checkingObjectWithThisInNamePositionNoCrash.ts] ////

=== checkingObjectWithThisInNamePositionNoCrash.ts ===
export const thing = {
>thing : { doit(): { [x: number]: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ doit() { return { [this.a]: "", // should refer to the outer object with the doit method, notably not present } }} : { doit(): { [x: number]: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

doit() {
>doit : () => { [x: number]: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

return {
>{ [this.a]: "", // should refer to the outer object with the doit method, notably not present } : { [x: number]: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^

[this.a]: "", // should refer to the outer object with the doit method, notably not present
>[this.a] : string
> : ^^^^^^
>this.a : any
> : ^^^
>this : { doit(): { [x: number]: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>a : any
> : ^^^
>"" : ""
> : ^^
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @strict: true
// @declaration: true
export const thing = {
doit() {
return {
[this.a]: "", // should refer to the outer object with the doit method, notably not present
}
}
}

0 comments on commit 517da72

Please sign in to comment.