@@ -6800,6 +6800,7 @@ namespace ts {
6800
6800
...!length(baseTypes) ? [] : [factory.createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))],
6801
6801
...!length(implementsExpressions) ? [] : [factory.createHeritageClause(SyntaxKind.ImplementsKeyword, implementsExpressions)]
6802
6802
];
6803
+ const modifiers = originalDecl && hasEffectiveModifier(originalDecl, ModifierFlags.Abstract) ? factory.createModifiersFromModifierFlags(ModifierFlags.Abstract) : undefined;
6803
6804
const symbolProps = getNonInterhitedProperties(classType, baseTypes, getPropertiesOfType(classType));
6804
6805
const publicSymbolProps = filter(symbolProps, s => {
6805
6806
// `valueDeclaration` could be undefined if inherited from
@@ -6846,7 +6847,7 @@ namespace ts {
6846
6847
context.enclosingDeclaration = oldEnclosing;
6847
6848
addResult(setTextRange(factory.createClassDeclaration(
6848
6849
/*decorators*/ undefined,
6849
- /* modifiers*/ undefined ,
6850
+ modifiers,
6850
6851
localName,
6851
6852
typeParamDecls,
6852
6853
heritageClauses,
@@ -7188,20 +7189,11 @@ namespace ts {
7188
7189
initializer: Expression | undefined
7189
7190
) => T, methodKind: SignatureDeclaration["kind"], useAccessors: boolean): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | AccessorDeclaration | (T | AccessorDeclaration)[]) {
7190
7191
return function serializePropertySymbol(p: Symbol, isStatic: boolean, baseType: Type | undefined): (T | AccessorDeclaration | (T | AccessorDeclaration)[]) {
7191
- const modifierFlags = getDeclarationModifierFlagsFromSymbol(p);
7192
- const isPrivate = !!(modifierFlags & ModifierFlags.Private);
7193
- if (isStatic && (p.flags & (SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias))) {
7194
- // Only value-only-meaning symbols can be correctly encoded as class statics, type/namespace/alias meaning symbols
7195
- // need to be merged namespace members
7196
- return [];
7197
- }
7198
- if (p.flags & SymbolFlags.Prototype ||
7199
- (baseType && getPropertyOfType(baseType, p.escapedName)
7200
- && isReadonlySymbol(getPropertyOfType(baseType, p.escapedName)!) === isReadonlySymbol(p)
7201
- && (p.flags & SymbolFlags.Optional) === (getPropertyOfType(baseType, p.escapedName)!.flags & SymbolFlags.Optional)
7202
- && isTypeIdenticalTo(getTypeOfSymbol(p), getTypeOfPropertyOfType(baseType, p.escapedName)!))) {
7192
+ if (isOmittedSerializationProperty(p, isStatic, baseType)) {
7203
7193
return [];
7204
7194
}
7195
+ const modifierFlags = getDeclarationModifierFlagsFromSymbol(p);
7196
+ const isPrivate = !!(modifierFlags & ModifierFlags.Private);
7205
7197
const flag = (modifierFlags & ~ModifierFlags.Async) | (isStatic ? ModifierFlags.Static : 0);
7206
7198
const name = getPropertyNameNodeForSymbol(p, context);
7207
7199
const firstPropertyLikeDecl = find(p.declarations, or(isPropertyDeclaration, isAccessor, isVariableDeclaration, isPropertySignature, isBinaryExpression, isPropertyAccessExpression));
@@ -7286,6 +7278,29 @@ namespace ts {
7286
7278
};
7287
7279
}
7288
7280
7281
+ function isOmittedSerializationProperty(prop: Symbol, isStatic: boolean, type: Type | undefined) {
7282
+ // Only value-only-meaning symbols can be correctly encoded as class statics, type/namespace/alias meaning symbols
7283
+ // need to be merged namespace members
7284
+ if (isStatic && (prop.flags & (SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias)) || (prop.flags & SymbolFlags.Prototype)) {
7285
+ return true;
7286
+ }
7287
+ if (type) {
7288
+ const baseProp = getPropertyOfType(type, prop.escapedName);
7289
+ const basePropType = getTypeOfPropertyOfType(type, prop.escapedName);
7290
+ if (baseProp && basePropType) {
7291
+ if (getDeclarationModifierFlagsFromSymbol(baseProp) & ModifierFlags.Abstract) {
7292
+ return prop === baseProp;
7293
+ }
7294
+ return (
7295
+ (prop.flags & SymbolFlags.Optional) === (baseProp.flags & SymbolFlags.Optional) &&
7296
+ isReadonlySymbol(baseProp) === isReadonlySymbol(prop) &&
7297
+ isTypeIdenticalTo(getTypeOfSymbol(prop), basePropType)
7298
+ );
7299
+ }
7300
+ }
7301
+ return false;
7302
+ }
7303
+
7289
7304
function serializePropertySymbolForInterface(p: Symbol, baseType: Type | undefined) {
7290
7305
return serializePropertySymbolForInterfaceWorker(p, /*isStatic*/ false, baseType);
7291
7306
}
@@ -28036,7 +28051,7 @@ namespace ts {
28036
28051
// In the case of a merged class-module or class-interface declaration,
28037
28052
// only the class declaration node will have the Abstract flag set.
28038
28053
const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol);
28039
- if (valueDecl && hasSyntacticModifier (valueDecl, ModifierFlags.Abstract)) {
28054
+ if (valueDecl && hasEffectiveModifier (valueDecl, ModifierFlags.Abstract)) {
28040
28055
error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class);
28041
28056
return resolveErrorCall(node);
28042
28057
}
@@ -29531,7 +29546,7 @@ namespace ts {
29531
29546
if (type && type.flags & TypeFlags.Never) {
29532
29547
error(getEffectiveReturnTypeNode(func), Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
29533
29548
}
29534
- else if (type && !hasExplicitReturn) {
29549
+ else if (type && !hasExplicitReturn && !hasEffectiveModifier(func, ModifierFlags.Abstract) ) {
29535
29550
// minimal check: function has syntactic return type annotation and no explicit return statements in the body
29536
29551
// this function does not conform to the specification.
29537
29552
// NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
@@ -31899,7 +31914,7 @@ namespace ts {
31899
31914
31900
31915
// Abstract methods cannot have an implementation.
31901
31916
// Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node.
31902
- if (hasSyntacticModifier (node, ModifierFlags.Abstract) && node.kind === SyntaxKind.MethodDeclaration && node.body) {
31917
+ if (hasEffectiveModifier (node, ModifierFlags.Abstract) && node.kind === SyntaxKind.MethodDeclaration && node.body && !isInJSFile(node) ) {
31903
31918
error(node, Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, declarationNameToString(node.name));
31904
31919
}
31905
31920
}
@@ -31996,7 +32011,7 @@ namespace ts {
31996
32011
checkSignatureDeclaration(node);
31997
32012
if (node.kind === SyntaxKind.GetAccessor) {
31998
32013
if (!(node.flags & NodeFlags.Ambient) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) {
31999
- if (!(node.flags & NodeFlags.HasExplicitReturn)) {
32014
+ if (!(node.flags & NodeFlags.HasExplicitReturn) && !(isInJSFile(node) && hasEffectiveModifier(node, ModifierFlags.Abstract)) ) {
32000
32015
error(node.name, Diagnostics.A_get_accessor_must_return_a_value);
32001
32016
}
32002
32017
}
@@ -33277,6 +33292,15 @@ namespace ts {
33277
33292
checkSignatureDeclaration(node);
33278
33293
}
33279
33294
33295
+ function checkJSDocAbstractTag(node: JSDocAbstractTag): void {
33296
+ const host = getEffectiveJSDocHost(node);
33297
+ if (host && isClassElement(host)) {
33298
+ if (!hasEffectiveModifier(host.parent, ModifierFlags.Abstract)) {
33299
+ error(host, Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class);
33300
+ }
33301
+ }
33302
+ }
33303
+
33280
33304
function checkJSDocImplementsTag(node: JSDocImplementsTag): void {
33281
33305
const classLike = getEffectiveJSDocHost(node);
33282
33306
if (!classLike || !isClassDeclaration(classLike) && !isClassExpression(classLike)) {
@@ -35896,7 +35920,7 @@ namespace ts {
35896
35920
const properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType));
35897
35921
for (const prop of properties) {
35898
35922
const existing = seen.get(prop.escapedName);
35899
- if (existing && !isPropertyIdenticalTo(existing, prop)) {
35923
+ if (existing && !isPropertyIdenticalTo(existing, prop) && !(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.Abstract) ) {
35900
35924
seen.delete(prop.escapedName);
35901
35925
}
35902
35926
}
@@ -36969,6 +36993,8 @@ namespace ts {
36969
36993
return checkImportType(<ImportTypeNode>node);
36970
36994
case SyntaxKind.NamedTupleMember:
36971
36995
return checkNamedTupleMember(<NamedTupleMember>node);
36996
+ case SyntaxKind.JSDocAbstractTag:
36997
+ return checkJSDocAbstractTag(<JSDocAbstractTag>node);
36972
36998
case SyntaxKind.JSDocAugmentsTag:
36973
36999
return checkJSDocAugmentsTag(node as JSDocAugmentsTag);
36974
37000
case SyntaxKind.JSDocImplementsTag:
@@ -39851,7 +39877,7 @@ namespace ts {
39851
39877
return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, Diagnostics._0_expected, "{");
39852
39878
}
39853
39879
}
39854
- if (accessor.body && hasSyntacticModifier (accessor, ModifierFlags.Abstract)) {
39880
+ if (accessor.body && hasEffectiveModifier (accessor, ModifierFlags.Abstract) && !isInJSFile(accessor )) {
39855
39881
return grammarErrorOnNode(accessor, Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
39856
39882
}
39857
39883
if (accessor.typeParameters) {
0 commit comments