mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
Fix stack overflow when resolving default construct signatures (#17878)
* Fix stack overflow when resolving default construct signatures * No need for || emptyArray
This commit is contained in:
parent
45c62ac0a6
commit
a136f554a7
@ -5657,17 +5657,12 @@ namespace ts {
|
||||
else {
|
||||
// Combinations of function, class, enum and module
|
||||
let members = emptySymbols;
|
||||
let constructSignatures: Signature[] = emptyArray;
|
||||
let stringIndexInfo: IndexInfo = undefined;
|
||||
if (symbol.exports) {
|
||||
members = getExportsOfSymbol(symbol);
|
||||
}
|
||||
if (symbol.flags & SymbolFlags.Class) {
|
||||
const classType = getDeclaredTypeOfClassOrInterface(symbol);
|
||||
constructSignatures = getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor));
|
||||
if (!constructSignatures.length) {
|
||||
constructSignatures = getDefaultConstructSignatures(classType);
|
||||
}
|
||||
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
|
||||
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) {
|
||||
members = createSymbolTable(getNamedMembers(members));
|
||||
@ -5678,7 +5673,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
const numberIndexInfo = symbol.flags & SymbolFlags.Enum ? enumNumberIndexInfo : undefined;
|
||||
setStructuredTypeMembers(type, members, emptyArray, constructSignatures, stringIndexInfo, numberIndexInfo);
|
||||
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
// We resolve the members before computing the signatures because a signature may use
|
||||
// typeof with a qualified name expression that circularly references the type we are
|
||||
// in the process of resolving (see issue #6072). The temporarily empty signature list
|
||||
@ -5686,6 +5681,15 @@ namespace ts {
|
||||
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
|
||||
(<ResolvedType>type).callSignatures = getSignaturesOfSymbol(symbol);
|
||||
}
|
||||
// And likewise for construct signatures for classes
|
||||
if (symbol.flags & SymbolFlags.Class) {
|
||||
const classType = getDeclaredTypeOfClassOrInterface(symbol);
|
||||
let constructSignatures = getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor));
|
||||
if (!constructSignatures.length) {
|
||||
constructSignatures = getDefaultConstructSignatures(classType);
|
||||
}
|
||||
(<ResolvedType>type).constructSignatures = constructSignatures;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
42
tests/baselines/reference/cloduleGenericOnSelfMember.js
Normal file
42
tests/baselines/reference/cloduleGenericOnSelfMember.js
Normal file
@ -0,0 +1,42 @@
|
||||
//// [cloduleGenericOnSelfMember.ts]
|
||||
class ServiceBase<T> {
|
||||
field: T;
|
||||
}
|
||||
class Service extends ServiceBase<typeof Service.Base> {
|
||||
}
|
||||
namespace Service {
|
||||
export const Base = {
|
||||
name: "1",
|
||||
value: 5
|
||||
};
|
||||
}
|
||||
|
||||
//// [cloduleGenericOnSelfMember.js]
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var ServiceBase = /** @class */ (function () {
|
||||
function ServiceBase() {
|
||||
}
|
||||
return ServiceBase;
|
||||
}());
|
||||
var Service = /** @class */ (function (_super) {
|
||||
__extends(Service, _super);
|
||||
function Service() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return Service;
|
||||
}(ServiceBase));
|
||||
(function (Service) {
|
||||
Service.Base = {
|
||||
name: "1",
|
||||
value: 5
|
||||
};
|
||||
})(Service || (Service = {}));
|
||||
30
tests/baselines/reference/cloduleGenericOnSelfMember.symbols
Normal file
30
tests/baselines/reference/cloduleGenericOnSelfMember.symbols
Normal file
@ -0,0 +1,30 @@
|
||||
=== tests/cases/compiler/cloduleGenericOnSelfMember.ts ===
|
||||
class ServiceBase<T> {
|
||||
>ServiceBase : Symbol(ServiceBase, Decl(cloduleGenericOnSelfMember.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(cloduleGenericOnSelfMember.ts, 0, 18))
|
||||
|
||||
field: T;
|
||||
>field : Symbol(ServiceBase.field, Decl(cloduleGenericOnSelfMember.ts, 0, 22))
|
||||
>T : Symbol(T, Decl(cloduleGenericOnSelfMember.ts, 0, 18))
|
||||
}
|
||||
class Service extends ServiceBase<typeof Service.Base> {
|
||||
>Service : Symbol(Service, Decl(cloduleGenericOnSelfMember.ts, 2, 1), Decl(cloduleGenericOnSelfMember.ts, 4, 1))
|
||||
>ServiceBase : Symbol(ServiceBase, Decl(cloduleGenericOnSelfMember.ts, 0, 0))
|
||||
>Service.Base : Symbol(Service.Base, Decl(cloduleGenericOnSelfMember.ts, 6, 16))
|
||||
>Service : Symbol(Service, Decl(cloduleGenericOnSelfMember.ts, 2, 1), Decl(cloduleGenericOnSelfMember.ts, 4, 1))
|
||||
>Base : Symbol(Service.Base, Decl(cloduleGenericOnSelfMember.ts, 6, 16))
|
||||
}
|
||||
namespace Service {
|
||||
>Service : Symbol(Service, Decl(cloduleGenericOnSelfMember.ts, 2, 1), Decl(cloduleGenericOnSelfMember.ts, 4, 1))
|
||||
|
||||
export const Base = {
|
||||
>Base : Symbol(Base, Decl(cloduleGenericOnSelfMember.ts, 6, 16))
|
||||
|
||||
name: "1",
|
||||
>name : Symbol(name, Decl(cloduleGenericOnSelfMember.ts, 6, 25))
|
||||
|
||||
value: 5
|
||||
>value : Symbol(value, Decl(cloduleGenericOnSelfMember.ts, 7, 18))
|
||||
|
||||
};
|
||||
}
|
||||
33
tests/baselines/reference/cloduleGenericOnSelfMember.types
Normal file
33
tests/baselines/reference/cloduleGenericOnSelfMember.types
Normal file
@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/cloduleGenericOnSelfMember.ts ===
|
||||
class ServiceBase<T> {
|
||||
>ServiceBase : ServiceBase<T>
|
||||
>T : T
|
||||
|
||||
field: T;
|
||||
>field : T
|
||||
>T : T
|
||||
}
|
||||
class Service extends ServiceBase<typeof Service.Base> {
|
||||
>Service : Service
|
||||
>ServiceBase : ServiceBase<{ name: string; value: number; }>
|
||||
>Service.Base : { name: string; value: number; }
|
||||
>Service : typeof Service
|
||||
>Base : { name: string; value: number; }
|
||||
}
|
||||
namespace Service {
|
||||
>Service : typeof Service
|
||||
|
||||
export const Base = {
|
||||
>Base : { name: string; value: number; }
|
||||
>{ name: "1", value: 5 } : { name: string; value: number; }
|
||||
|
||||
name: "1",
|
||||
>name : string
|
||||
>"1" : "1"
|
||||
|
||||
value: 5
|
||||
>value : number
|
||||
>5 : 5
|
||||
|
||||
};
|
||||
}
|
||||
11
tests/cases/compiler/cloduleGenericOnSelfMember.ts
Normal file
11
tests/cases/compiler/cloduleGenericOnSelfMember.ts
Normal file
@ -0,0 +1,11 @@
|
||||
class ServiceBase<T> {
|
||||
field: T;
|
||||
}
|
||||
class Service extends ServiceBase<typeof Service.Base> {
|
||||
}
|
||||
namespace Service {
|
||||
export const Base = {
|
||||
name: "1",
|
||||
value: 5
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user