@@ -4590,8 +4590,12 @@ namespace ts {
4590
4590
returnTypeNode = createKeywordTypeNode(SyntaxKind.AnyKeyword);
4591
4591
}
4592
4592
}
4593
+ let modifiers: Modifier[] | undefined;
4594
+ if ((kind === SyntaxKind.ConstructorType || kind === SyntaxKind.ConstructSignature) && signature.flags & SignatureFlags.Abstract) {
4595
+ modifiers = createModifiersFromModifierFlags(ModifierFlags.Abstract);
4596
+ }
4593
4597
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);
4595
4599
}
4596
4600
4597
4601
function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration {
@@ -8994,8 +8998,10 @@ namespace ts {
8994
8998
function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
8995
8999
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
8996
9000
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
9001
+ const declaration = getClassLikeDeclarationOfSymbol(classType.symbol);
9002
+ const isAbstract = !!declaration && hasModifier(declaration, ModifierFlags.Abstract);
8997
9003
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)];
8999
9005
}
9000
9006
const baseTypeNode = getBaseTypeNodeOfClass(classType)!;
9001
9007
const isJavaScript = isInJSFile(baseTypeNode);
@@ -9009,6 +9015,7 @@ namespace ts {
9009
9015
const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig);
9010
9016
sig.typeParameters = classType.localTypeParameters;
9011
9017
sig.resolvedReturnType = classType;
9018
+ sig.flags = isAbstract ? sig.flags | SignatureFlags.Abstract : sig.flags & ~SignatureFlags.Abstract;
9012
9019
result.push(sig);
9013
9020
}
9014
9021
}
@@ -10403,6 +10410,10 @@ namespace ts {
10403
10410
if (hasRestParameter(declaration) || isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters)) {
10404
10411
flags |= SignatureFlags.HasRestParameter;
10405
10412
}
10413
+ if ((isConstructSignatureDeclaration(declaration) || isConstructorTypeNode(declaration)) && hasModifier(declaration, ModifierFlags.Abstract) ||
10414
+ isConstructorDeclaration(declaration) && hasModifier(declaration.parent, ModifierFlags.Abstract)) {
10415
+ flags |= SignatureFlags.Abstract;
10416
+ }
10406
10417
links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters,
10407
10418
/*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined,
10408
10419
minArgumentCount, flags);
@@ -16174,7 +16185,9 @@ namespace ts {
16174
16185
SignatureKind.Call : kind);
16175
16186
16176
16187
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) {
16178
16191
// An abstract constructor type is not assignable to a non-abstract constructor type
16179
16192
// as it would otherwise be possible to new an abstract class. Note that the assignability
16180
16193
// check we perform for an extends clause excludes construct signatures from the target,
@@ -25067,8 +25080,7 @@ namespace ts {
25067
25080
// Note, only class declarations can be declared abstract.
25068
25081
// In the case of a merged class-module or class-interface declaration,
25069
25082
// 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) {
25072
25084
error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class);
25073
25085
return resolveErrorCall(node);
25074
25086
}
@@ -28687,6 +28699,33 @@ namespace ts {
28687
28699
}
28688
28700
}
28689
28701
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
+
28690
28729
function checkAccessorDeclaration(node: AccessorDeclaration) {
28691
28730
if (produceDiagnostics) {
28692
28731
// Grammar checking accessors
@@ -28966,44 +29005,43 @@ namespace ts {
28966
29005
return flags & flagsToCheck;
28967
29006
}
28968
29007
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
+ }
28973
29017
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
+ });
28982
29039
}
29040
+ }
28983
29041
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;
29007
29045
}
29008
29046
29009
29047
function checkQuestionTokenAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined, someHaveQuestionToken: boolean, allHaveQuestionToken: boolean): void {
@@ -33331,10 +33369,11 @@ namespace ts {
33331
33369
return checkPropertyDeclaration(<PropertyDeclaration>node);
33332
33370
case SyntaxKind.PropertySignature:
33333
33371
return checkPropertySignature(<PropertySignature>node);
33334
- case SyntaxKind.FunctionType:
33372
+ case SyntaxKind.ConstructSignature:
33373
+ return checkConstructSignatureDeclaration(<ConstructSignatureDeclaration>node);
33335
33374
case SyntaxKind.ConstructorType:
33375
+ case SyntaxKind.FunctionType:
33336
33376
case SyntaxKind.CallSignature:
33337
- case SyntaxKind.ConstructSignature:
33338
33377
case SyntaxKind.IndexSignature:
33339
33378
return checkSignatureDeclaration(<SignatureDeclaration>node);
33340
33379
case SyntaxKind.MethodDeclaration:
@@ -35469,7 +35508,9 @@ namespace ts {
35469
35508
if (flags & ModifierFlags.Abstract) {
35470
35509
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "abstract");
35471
35510
}
35472
- if (node.kind !== SyntaxKind.ClassDeclaration) {
35511
+ if (node.kind !== SyntaxKind.ClassDeclaration &&
35512
+ node.kind !== SyntaxKind.ConstructorType &&
35513
+ node.kind !== SyntaxKind.ConstructSignature) {
35473
35514
if (node.kind !== SyntaxKind.MethodDeclaration &&
35474
35515
node.kind !== SyntaxKind.PropertyDeclaration &&
35475
35516
node.kind !== SyntaxKind.GetAccessor &&
@@ -35580,6 +35621,8 @@ namespace ts {
35580
35621
case SyntaxKind.FunctionDeclaration:
35581
35622
return nodeHasAnyModifiersExcept(node, SyntaxKind.AsyncKeyword);
35582
35623
case SyntaxKind.ClassDeclaration:
35624
+ case SyntaxKind.ConstructorType:
35625
+ case SyntaxKind.ConstructSignature:
35583
35626
return nodeHasAnyModifiersExcept(node, SyntaxKind.AbstractKeyword);
35584
35627
case SyntaxKind.InterfaceDeclaration:
35585
35628
case SyntaxKind.VariableStatement:
@@ -35589,7 +35632,6 @@ namespace ts {
35589
35632
return nodeHasAnyModifiersExcept(node, SyntaxKind.ConstKeyword);
35590
35633
default:
35591
35634
Debug.fail();
35592
- return false;
35593
35635
}
35594
35636
}
35595
35637
}
0 commit comments