From 4aa04a93b3b0c74d2859801e289a978ff2298f79 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 17 Sep 2014 16:36:38 -0700 Subject: [PATCH] Addressing CR feedback --- src/compiler/checker.ts | 17 +++++++++++++---- src/compiler/diagnosticMessages.json | 12 ++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c6d61c7954..8b3f21bf0b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2713,12 +2713,12 @@ module ts { if (sourceProp === targetProp) { return true; } - var sourcePropVisibility = getDeclarationFlagsFromSymbol(sourceProp) & (NodeFlags.Private || NodeFlags.Protected); - var targetPropVisibility = getDeclarationFlagsFromSymbol(targetProp) & (NodeFlags.Private || NodeFlags.Protected); - if (sourcePropVisibility !== targetPropVisibility) { + var sourcePropAccessibility = getDeclarationFlagsFromSymbol(sourceProp) & (NodeFlags.Private | NodeFlags.Protected); + var targetPropAccessibility = getDeclarationFlagsFromSymbol(targetProp) & (NodeFlags.Private | NodeFlags.Protected); + if (sourcePropAccessibility !== targetPropAccessibility) { return false; } - if (sourcePropVisibility) { + if (sourcePropAccessibility) { return getTargetSymbol(sourceProp) === getTargetSymbol(targetProp) && relate(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp), reportErrors); } else { @@ -4011,26 +4011,35 @@ module ts { function isClassPropertyAccessible(node: PropertyAccess, type: Type, prop: Symbol): boolean { var flags = getDeclarationFlagsFromSymbol(prop); + // Public properties are always accessible if (!(flags & (NodeFlags.Private | NodeFlags.Protected))) { return true; } + // Property is known to be private or protected at this point + // Private and protected properties are never accessible outside a class declaration var enclosingClassDeclaration = getAncestor(node, SyntaxKind.ClassDeclaration); if (!enclosingClassDeclaration) { return false; } + // Get the declaring and enclosing class instance types var declaringClass = getDeclaredTypeOfSymbol(prop.parent); var enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClassDeclaration)); + // Private property is accessible if declaring and enclosing class are the same if (flags & NodeFlags.Private) { return declaringClass === enclosingClass; } + // Property is known to be protected at this point + // All protected properties of a supertype are accessible in a super access if (node.left.kind === SyntaxKind.SuperKeyword) { return true; } + // An instance property must be accessed through an instance of the enclosing class if (!(flags & NodeFlags.Static)) { if (!(getTargetType(type).flags & (TypeFlags.Class | TypeFlags.Interface) && hasBaseType(type, enclosingClass))) { return false; } } + // A protected property is accessible in the declaring class and classes derived from it return hasBaseType(enclosingClass, declaringClass); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2e4ed8ce7a..ba2c87180c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1012,18 +1012,18 @@ "category": "Error", "code": 2441 }, - "Types have separate declarations of a private property '{0}'.": { + "Types have separate declarations of a private property '{0}'.": { "category": "Error", "code": 2442 - }, - "Property '{0}' is protected but type '{1}' is not derived from type '{2}'.": { + }, + "Property '{0}' is protected but type '{1}' is not a class derived from type '{2}'.": { "category": "Error", "code": 2443 - }, - "Property '{0}' is protected in type '{1}' but public in type '{2}'.": { + }, + "Property '{0}' is protected in type '{1}' but public in type '{2}'.": { "category": "Error", "code": 2444 - }, + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error",