@@ -2713,12 +2713,12 @@ module ts {
27132713 if ( sourceProp === targetProp ) {
27142714 return true ;
27152715 }
2716- var sourcePropVisibility = getDeclarationFlagsFromSymbol ( sourceProp ) & ( NodeFlags . Private | | NodeFlags . Protected ) ;
2717- var targetPropVisibility = getDeclarationFlagsFromSymbol ( targetProp ) & ( NodeFlags . Private | | NodeFlags . Protected ) ;
2718- if ( sourcePropVisibility !== targetPropVisibility ) {
2716+ var sourcePropAccessibility = getDeclarationFlagsFromSymbol ( sourceProp ) & ( NodeFlags . Private | NodeFlags . Protected ) ;
2717+ var targetPropAccessibility = getDeclarationFlagsFromSymbol ( targetProp ) & ( NodeFlags . Private | NodeFlags . Protected ) ;
2718+ if ( sourcePropAccessibility !== targetPropAccessibility ) {
27192719 return false ;
27202720 }
2721- if ( sourcePropVisibility ) {
2721+ if ( sourcePropAccessibility ) {
27222722 return getTargetSymbol ( sourceProp ) === getTargetSymbol ( targetProp ) && relate ( getTypeOfSymbol ( sourceProp ) , getTypeOfSymbol ( targetProp ) , reportErrors ) ;
27232723 }
27242724 else {
@@ -4011,26 +4011,35 @@ module ts {
40114011
40124012 function isClassPropertyAccessible ( node : PropertyAccess , type : Type , prop : Symbol ) : boolean {
40134013 var flags = getDeclarationFlagsFromSymbol ( prop ) ;
4014+ // Public properties are always accessible
40144015 if ( ! ( flags & ( NodeFlags . Private | NodeFlags . Protected ) ) ) {
40154016 return true ;
40164017 }
4018+ // Property is known to be private or protected at this point
4019+ // Private and protected properties are never accessible outside a class declaration
40174020 var enclosingClassDeclaration = getAncestor ( node , SyntaxKind . ClassDeclaration ) ;
40184021 if ( ! enclosingClassDeclaration ) {
40194022 return false ;
40204023 }
4024+ // Get the declaring and enclosing class instance types
40214025 var declaringClass = < InterfaceType > getDeclaredTypeOfSymbol ( prop . parent ) ;
40224026 var enclosingClass = < InterfaceType > getDeclaredTypeOfSymbol ( getSymbolOfNode ( enclosingClassDeclaration ) ) ;
4027+ // Private property is accessible if declaring and enclosing class are the same
40234028 if ( flags & NodeFlags . Private ) {
40244029 return declaringClass === enclosingClass ;
40254030 }
4031+ // Property is known to be protected at this point
4032+ // All protected properties of a supertype are accessible in a super access
40264033 if ( node . left . kind === SyntaxKind . SuperKeyword ) {
40274034 return true ;
40284035 }
4036+ // An instance property must be accessed through an instance of the enclosing class
40294037 if ( ! ( flags & NodeFlags . Static ) ) {
40304038 if ( ! ( getTargetType ( type ) . flags & ( TypeFlags . Class | TypeFlags . Interface ) && hasBaseType ( < InterfaceType > type , enclosingClass ) ) ) {
40314039 return false ;
40324040 }
40334041 }
4042+ // A protected property is accessible in the declaring class and classes derived from it
40344043 return hasBaseType ( enclosingClass , declaringClass ) ;
40354044 }
40364045
0 commit comments