Skip to content

Commit f2719f9

Browse files
authoredAug 9, 2019
Allow functions and ambient classes to merge (#32584)
·
v5.9.2v3.6-rc
1 parent b84e65d commit f2719f9

File tree

78 files changed

+488
-445
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+488
-445
lines changed
 

‎src/compiler/checker.ts‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26276,8 +26276,9 @@ namespace ts {
2627626276

2627726277
let duplicateFunctionDeclaration = false;
2627826278
let multipleConstructorImplementation = false;
26279+
let hasNonAmbientClass = false;
2627926280
for (const current of declarations) {
26280-
const node = <SignatureDeclaration>current;
26281+
const node = <SignatureDeclaration | ClassDeclaration | ClassExpression>current;
2628126282
const inAmbientContext = node.flags & NodeFlags.Ambient;
2628226283
const inAmbientContextOrInterface = node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.TypeLiteral || inAmbientContext;
2628326284
if (inAmbientContextOrInterface) {
@@ -26291,6 +26292,10 @@ namespace ts {
2629126292
previousDeclaration = undefined;
2629226293
}
2629326294

26295+
if ((node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && !inAmbientContext) {
26296+
hasNonAmbientClass = true;
26297+
}
26298+
2629426299
if (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature || node.kind === SyntaxKind.Constructor) {
2629526300
const currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
2629626301
someNodeFlags |= currentNodeFlags;
@@ -26339,6 +26344,16 @@ namespace ts {
2633926344
});
2634026345
}
2634126346

26347+
if (hasNonAmbientClass && !isConstructor && symbol.flags & SymbolFlags.Function) {
26348+
// A non-ambient class cannot be an implementation for a non-constructor function/class merge
26349+
// TODO: The below just replicates our older error from when classes and functions were
26350+
// entirely unable to merge - a more helpful message like "Class declaration cannot implement overload list"
26351+
// might be warranted. :shrug:
26352+
forEach(declarations, declaration => {
26353+
addDuplicateDeclarationError(getNameOfDeclaration(declaration) || declaration, Diagnostics.Duplicate_identifier_0, symbolName(symbol), filter(declarations, d => d !== declaration));
26354+
});
26355+
}
26356+
2634226357
// Abstract methods can't have an implementation -- in particular, they don't need one.
2634326358
if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
2634426359
!hasModifier(lastSeenNonAmbientDeclaration, ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) {
@@ -31650,7 +31665,7 @@ namespace ts {
3165031665
if (!symbol || !(symbol.flags & SymbolFlags.Function)) {
3165131666
return false;
3165231667
}
31653-
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && isPropertyAccessExpression(p.valueDeclaration));
31668+
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && p.valueDeclaration && isPropertyAccessExpression(p.valueDeclaration));
3165431669
}
3165531670

3165631671
function getPropertiesOfContainerFunction(node: Declaration): Symbol[] {

‎src/compiler/types.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3678,8 +3678,8 @@ namespace ts {
36783678
ParameterExcludes = Value,
36793679
PropertyExcludes = None,
36803680
EnumMemberExcludes = Value | Type,
3681-
FunctionExcludes = Value & ~(Function | ValueModule),
3682-
ClassExcludes = (Value | Type) & ~(ValueModule | Interface), // class-interface mergability done in checker.ts
3681+
FunctionExcludes = Value & ~(Function | ValueModule | Class),
3682+
ClassExcludes = (Value | Type) & ~(ValueModule | Interface | Function), // class-interface mergability done in checker.ts
36833683
InterfaceExcludes = Type & ~(Interface | Class),
36843684
RegularEnumExcludes = (Value | Type) & ~(RegularEnum | ValueModule), // regular enums merge only with regular enums and modules
36853685
ConstEnumExcludes = (Value | Type) & ~ConstEnum, // const enums merge only with const enums

0 commit comments

Comments
 (0)