From 8ef9599bac0a4559119de60907fcdfb8cded3465 Mon Sep 17 00:00:00 2001 From: AbubakerB Date: Sat, 13 Feb 2016 01:07:33 +0000 Subject: [PATCH] Allow extending and instantiating a private or protected class within itself --- src/compiler/checker.ts | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2d1bd26442e..d6b67c456ca 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10192,12 +10192,11 @@ namespace ts { return true; } + const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol); const declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol); - const enclosingClassDeclaration = getContainingClass(node); - const enclosingClass = enclosingClassDeclaration ? getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClassDeclaration)) : undefined; // A private or protected constructor can only be instantiated within it's own class - if (declaringClass !== enclosingClass) { + if (!isNodeWithinClass(node, declaringClassDeclaration)) { if (flags & NodeFlags.Private) { error(node, Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); } @@ -14076,11 +14075,14 @@ namespace ts { } function checkBaseTypeAccessibility(type: ObjectType, node: ExpressionWithTypeArguments) { - const signatures = getSignaturesOfType(type, SignatureKind.Construct); - if (signatures.length) { - const declaration = signatures[0].declaration; - if (declaration && declaration.flags & NodeFlags.Private) { - error(node, Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, (node.expression).text); + const typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); + if (!isNodeWithinClass(node, typeClassDeclaration)) { + const signatures = getSignaturesOfType(type, SignatureKind.Construct); + if (signatures.length) { + const declaration = signatures[0].declaration; + if (declaration && declaration.flags & NodeFlags.Private) { + error(node, Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, (node.expression).text); + } } } } @@ -15408,6 +15410,19 @@ namespace ts { return node.parent && node.parent.kind === SyntaxKind.ExpressionWithTypeArguments; } + function isNodeWithinClass(node: Node, classDeclaration: ClassLikeDeclaration) { + while (true) { + const containingClass = getContainingClass(node); + if (!containingClass) { + return false; + } + if (containingClass === classDeclaration) { + return true; + } + node = containingClass; + } + } + function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide: EntityName): ImportEqualsDeclaration | ExportAssignment { while (nodeOnRightSide.parent.kind === SyntaxKind.QualifiedName) { nodeOnRightSide = nodeOnRightSide.parent;