@@ -4590,8 +4590,12 @@ namespace ts {
45904590 returnTypeNode = createKeywordTypeNode(SyntaxKind.AnyKeyword);
45914591 }
45924592 }
4593+ let modifiers: Modifier[] | undefined;
4594+ if ((kind === SyntaxKind.ConstructorType || kind === SyntaxKind.ConstructSignature) && signature.flags & SignatureFlags.Abstract) {
4595+ modifiers = createModifiersFromModifierFlags(ModifierFlags.Abstract);
4596+ }
45934597 context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum
4594- return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments);
4598+ return createSignatureDeclaration(kind, modifiers, typeParameters, parameters, returnTypeNode, typeArguments);
45954599 }
45964600
45974601 function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration {
@@ -8994,8 +8998,10 @@ namespace ts {
89948998 function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
89958999 const baseConstructorType = getBaseConstructorTypeOfClass(classType);
89969000 const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
9001+ const declaration = getClassLikeDeclarationOfSymbol(classType.symbol);
9002+ const isAbstract = !!declaration && hasModifier(declaration, ModifierFlags.Abstract);
89979003 if (baseSignatures.length === 0) {
8998- return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None)];
9004+ return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, isAbstract ? SignatureFlags.Abstract : SignatureFlags.None)];
89999005 }
90009006 const baseTypeNode = getBaseTypeNodeOfClass(classType)!;
90019007 const isJavaScript = isInJSFile(baseTypeNode);
@@ -9009,6 +9015,7 @@ namespace ts {
90099015 const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig);
90109016 sig.typeParameters = classType.localTypeParameters;
90119017 sig.resolvedReturnType = classType;
9018+ sig.flags = isAbstract ? sig.flags | SignatureFlags.Abstract : sig.flags & ~SignatureFlags.Abstract;
90129019 result.push(sig);
90139020 }
90149021 }
@@ -10403,6 +10410,10 @@ namespace ts {
1040310410 if (hasRestParameter(declaration) || isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters)) {
1040410411 flags |= SignatureFlags.HasRestParameter;
1040510412 }
10413+ if ((isConstructSignatureDeclaration(declaration) || isConstructorTypeNode(declaration)) && hasModifier(declaration, ModifierFlags.Abstract) ||
10414+ isConstructorDeclaration(declaration) && hasModifier(declaration.parent, ModifierFlags.Abstract)) {
10415+ flags |= SignatureFlags.Abstract;
10416+ }
1040610417 links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters,
1040710418 /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined,
1040810419 minArgumentCount, flags);
@@ -16174,7 +16185,9 @@ namespace ts {
1617416185 SignatureKind.Call : kind);
1617516186
1617616187 if (kind === SignatureKind.Construct && sourceSignatures.length && targetSignatures.length) {
16177- if (isAbstractConstructorType(source) && !isAbstractConstructorType(target)) {
16188+ const sourceIsAbstract = !!(sourceSignatures[0].flags & SignatureFlags.Abstract);
16189+ const targetIsAbstract = !!(targetSignatures[0].flags & SignatureFlags.Abstract);
16190+ if (sourceIsAbstract && !targetIsAbstract) {
1617816191 // An abstract constructor type is not assignable to a non-abstract constructor type
1617916192 // as it would otherwise be possible to new an abstract class. Note that the assignability
1618016193 // check we perform for an extends clause excludes construct signatures from the target,
@@ -25067,8 +25080,7 @@ namespace ts {
2506725080 // Note, only class declarations can be declared abstract.
2506825081 // In the case of a merged class-module or class-interface declaration,
2506925082 // only the class declaration node will have the Abstract flag set.
25070- const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol);
25071- if (valueDecl && hasModifier(valueDecl, ModifierFlags.Abstract)) {
25083+ if (constructSignatures[0].flags & SignatureFlags.Abstract) {
2507225084 error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class);
2507325085 return resolveErrorCall(node);
2507425086 }
@@ -28687,6 +28699,33 @@ namespace ts {
2868728699 }
2868828700 }
2868928701
28702+ function checkConstructSignatureDeclaration(node: ConstructSignatureDeclaration) {
28703+ checkSignatureDeclaration(node);
28704+ if (produceDiagnostics) {
28705+ const symbol = getSymbolOfNode(node);
28706+ const firstDeclaration = getDeclarationOfKind(symbol, node.kind);
28707+ if (node === firstDeclaration) {
28708+ const flagsToCheck: ModifierFlags = ModifierFlags.Abstract;
28709+ let hasOverloads = false;
28710+ let someNodeFlags = ModifierFlags.None;
28711+ let allNodeFlags = flagsToCheck;
28712+ for (const declaration of symbol.declarations) {
28713+ if (isConstructSignatureDeclaration(declaration)) {
28714+ const currentNodeFlags = getEffectiveDeclarationFlags(declaration, flagsToCheck);
28715+ someNodeFlags |= currentNodeFlags;
28716+ allNodeFlags &= currentNodeFlags;
28717+ if (declaration !== node) {
28718+ hasOverloads = true;
28719+ }
28720+ }
28721+ }
28722+ if (hasOverloads) {
28723+ checkFlagAgreementBetweenOverloads(symbol.declarations, /*implementation*/ undefined, flagsToCheck, someNodeFlags, allNodeFlags);
28724+ }
28725+ }
28726+ }
28727+ }
28728+
2869028729 function checkAccessorDeclaration(node: AccessorDeclaration) {
2869128730 if (produceDiagnostics) {
2869228731 // Grammar checking accessors
@@ -28966,44 +29005,43 @@ namespace ts {
2896629005 return flags & flagsToCheck;
2896729006 }
2896829007
28969- function checkFunctionOrConstructorSymbol(symbol: Symbol): void {
28970- if (!produceDiagnostics) {
28971- return;
28972- }
29008+ function getCanonicalOverload(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined): Declaration {
29009+ // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
29010+ // Error on all deviations from this canonical set of flags
29011+ // The caveat is that if some overloads are defined in lib.d.ts, we don't want to
29012+ // report the errors on those. To achieve this, we will say that the implementation is
29013+ // the canonical signature only if it is in the same container as the first overload
29014+ const implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent;
29015+ return implementationSharesContainerWithFirstOverload ? implementation! : overloads[0];
29016+ }
2897329017
28974- function getCanonicalOverload(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined): Declaration {
28975- // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
28976- // Error on all deviations from this canonical set of flags
28977- // The caveat is that if some overloads are defined in lib.d.ts, we don't want to
28978- // report the errors on those. To achieve this, we will say that the implementation is
28979- // the canonical signature only if it is in the same container as the first overload
28980- const implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent;
28981- return implementationSharesContainerWithFirstOverload ? implementation! : overloads[0];
29018+ function checkFlagAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined, flagsToCheck: ModifierFlags, someOverloadFlags: ModifierFlags, allOverloadFlags: ModifierFlags): void {
29019+ // Error if some overloads have a flag that is not shared by all overloads. To find the
29020+ // deviations, we XOR someOverloadFlags with allOverloadFlags
29021+ const someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
29022+ if (someButNotAllOverloadFlags !== 0) {
29023+ const canonicalFlags = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck);
29024+ forEach(overloads, o => {
29025+ const deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags;
29026+ if (deviation & ModifierFlags.Export) {
29027+ error(getNameOfDeclaration(o) ?? o, Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
29028+ }
29029+ else if (deviation & ModifierFlags.Ambient) {
29030+ error(getNameOfDeclaration(o) ?? o, Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
29031+ }
29032+ else if (deviation & (ModifierFlags.Private | ModifierFlags.Protected)) {
29033+ error(getNameOfDeclaration(o) ?? o, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
29034+ }
29035+ else if (deviation & ModifierFlags.Abstract) {
29036+ error(getNameOfDeclaration(o) ?? o, Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract);
29037+ }
29038+ });
2898229039 }
29040+ }
2898329041
28984- function checkFlagAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined, flagsToCheck: ModifierFlags, someOverloadFlags: ModifierFlags, allOverloadFlags: ModifierFlags): void {
28985- // Error if some overloads have a flag that is not shared by all overloads. To find the
28986- // deviations, we XOR someOverloadFlags with allOverloadFlags
28987- const someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
28988- if (someButNotAllOverloadFlags !== 0) {
28989- const canonicalFlags = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck);
28990-
28991- forEach(overloads, o => {
28992- const deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags;
28993- if (deviation & ModifierFlags.Export) {
28994- error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
28995- }
28996- else if (deviation & ModifierFlags.Ambient) {
28997- error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
28998- }
28999- else if (deviation & (ModifierFlags.Private | ModifierFlags.Protected)) {
29000- error(getNameOfDeclaration(o) || o, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
29001- }
29002- else if (deviation & ModifierFlags.Abstract) {
29003- error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract);
29004- }
29005- });
29006- }
29042+ function checkFunctionOrConstructorSymbol(symbol: Symbol): void {
29043+ if (!produceDiagnostics) {
29044+ return;
2900729045 }
2900829046
2900929047 function checkQuestionTokenAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined, someHaveQuestionToken: boolean, allHaveQuestionToken: boolean): void {
@@ -33331,10 +33369,11 @@ namespace ts {
3333133369 return checkPropertyDeclaration(<PropertyDeclaration>node);
3333233370 case SyntaxKind.PropertySignature:
3333333371 return checkPropertySignature(<PropertySignature>node);
33334- case SyntaxKind.FunctionType:
33372+ case SyntaxKind.ConstructSignature:
33373+ return checkConstructSignatureDeclaration(<ConstructSignatureDeclaration>node);
3333533374 case SyntaxKind.ConstructorType:
33375+ case SyntaxKind.FunctionType:
3333633376 case SyntaxKind.CallSignature:
33337- case SyntaxKind.ConstructSignature:
3333833377 case SyntaxKind.IndexSignature:
3333933378 return checkSignatureDeclaration(<SignatureDeclaration>node);
3334033379 case SyntaxKind.MethodDeclaration:
@@ -35469,7 +35508,9 @@ namespace ts {
3546935508 if (flags & ModifierFlags.Abstract) {
3547035509 return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "abstract");
3547135510 }
35472- if (node.kind !== SyntaxKind.ClassDeclaration) {
35511+ if (node.kind !== SyntaxKind.ClassDeclaration &&
35512+ node.kind !== SyntaxKind.ConstructorType &&
35513+ node.kind !== SyntaxKind.ConstructSignature) {
3547335514 if (node.kind !== SyntaxKind.MethodDeclaration &&
3547435515 node.kind !== SyntaxKind.PropertyDeclaration &&
3547535516 node.kind !== SyntaxKind.GetAccessor &&
@@ -35580,6 +35621,8 @@ namespace ts {
3558035621 case SyntaxKind.FunctionDeclaration:
3558135622 return nodeHasAnyModifiersExcept(node, SyntaxKind.AsyncKeyword);
3558235623 case SyntaxKind.ClassDeclaration:
35624+ case SyntaxKind.ConstructorType:
35625+ case SyntaxKind.ConstructSignature:
3558335626 return nodeHasAnyModifiersExcept(node, SyntaxKind.AbstractKeyword);
3558435627 case SyntaxKind.InterfaceDeclaration:
3558535628 case SyntaxKind.VariableStatement:
@@ -35589,7 +35632,6 @@ namespace ts {
3558935632 return nodeHasAnyModifiersExcept(node, SyntaxKind.ConstKeyword);
3559035633 default:
3559135634 Debug.fail();
35592- return false;
3559335635 }
3559435636 }
3559535637 }
0 commit comments