Filter protected members from the completion list

This commit is contained in:
Mohamed Hegazy 2014-09-26 14:37:17 -07:00
parent 3e08af41fe
commit 8089673066
13 changed files with 512 additions and 14 deletions

View File

@ -92,7 +92,8 @@ module ts {
getContextualType: getContextualType,
getFullyQualifiedName: getFullyQualifiedName,
getResolvedSignature: getResolvedSignature,
getEnumMemberValue: getEnumMemberValue
getEnumMemberValue: getEnumMemberValue,
isValidPropertyAccess: isValidPropertyAccess
};
var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined");
@ -4239,6 +4240,25 @@ module ts {
return anyType;
}
function isValidPropertyAccess(node: PropertyAccess, propertyName: string): boolean {
var type = checkExpression(node.left);
if (type !== unknownType && type !== anyType) {
var apparentType = getApparentType(getWidenedType(type));
var prop = getPropertyOfApparentType(apparentType, propertyName);
if (prop && prop.parent && prop.parent.flags & SymbolFlags.Class) {
if (node.left.kind === SyntaxKind.SuperKeyword && getDeclarationKindFromSymbol(prop) !== SyntaxKind.Method) {
return false;
}
else {
var diagnosticsCount = diagnostics.length;
checkClassPropertyAccess(node, type, prop);
return diagnostics.length === diagnosticsCount
}
}
}
return true;
}
function checkIndexedAccess(node: IndexedAccess): Type {
var objectType = checkExpression(node.object);
var indexType = checkExpression(node.index);

View File

@ -655,6 +655,8 @@ module ts {
// Returns the constant value of this enum member, or 'undefined' if the enum member has a
// computed value.
getEnumMemberValue(node: EnumMember): number;
isValidPropertyAccess(node: PropertyAccess, propertyName: string): boolean;
}
export interface TextWriter {

View File

@ -2038,15 +2038,6 @@ module ts {
return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation);
}
function isVisibleWithinClassDeclaration(symbol: Symbol, containingClass: Declaration): boolean {
var declaration = symbol.declarations && symbol.declarations[0];
if (declaration && (declaration.flags & NodeFlags.Private)) {
var declarationClass = getAncestor(declaration, SyntaxKind.ClassDeclaration);
return containingClass === declarationClass;
}
return true;
}
function filterContextualMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] {
if (!existingMembers || existingMembers.length === 0) {
return contextualMemberSymbols;
@ -2150,7 +2141,6 @@ module ts {
// Right of dot member completion list
if (isRightOfDot) {
var symbols: Symbol[] = [];
var containingClass = getAncestor(mappedNode, SyntaxKind.ClassDeclaration);
isMemberCompletion = true;
if (mappedNode.kind === SyntaxKind.Identifier || mappedNode.kind === SyntaxKind.QualifiedName || mappedNode.kind === SyntaxKind.PropertyAccess) {
@ -2158,7 +2148,7 @@ module ts {
if (symbol && symbol.flags & SymbolFlags.HasExports) {
// Extract module or enum members
forEachValue(symbol.exports, symbol => {
if (isVisibleWithinClassDeclaration(symbol, containingClass)) {
if (typeInfoResolver.isValidPropertyAccess(<PropertyAccess>(mappedNode.parent), symbol.name)) {
symbols.push(symbol);
}
});
@ -2170,7 +2160,7 @@ module ts {
if (apparentType) {
// Filter private properties
forEach(apparentType.getApparentProperties(), symbol => {
if (isVisibleWithinClassDeclaration(symbol, containingClass)) {
if (typeInfoResolver.isValidPropertyAccess(<PropertyAccess>(mappedNode.parent), symbol.name)) {
symbols.push(symbol);
}
});

View File

@ -0,0 +1,63 @@
/// <reference path='fourslash.ts'/>
////class Base {
//// private privateMethod() { }
//// private privateProperty;
////
//// protected protectedMethod() { }
//// protected protectedProperty;
////
//// public publicMethod() { }
//// public publicProperty;
////
//// protected protectedOverriddenMethod() { }
//// protected protectedOverriddenProperty;
////
//// test() {
//// this./*1*/;
////
//// var b: Base;
//// var c: C1;
////
//// b./*2*/;
//// c./*3*/;
//// }
////}
////
////class C1 extends Base {
//// protected protectedOverriddenMethod() { }
//// protected protectedOverriddenProperty;
////}
// Same class, everything is visible
goTo.marker("1");
verify.memberListContains('privateMethod');
verify.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');
goTo.marker("2");
verify.memberListContains('privateMethod');
verify.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');
// Can not access protected properties overridden in subclass
goTo.marker("3");
verify.memberListContains('privateMethod');
verify.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.not.memberListContains('protectedOverriddenMethod');
verify.not.memberListContains('protectedOverriddenProperty');

View File

@ -0,0 +1,76 @@
/// <reference path='fourslash.ts'/>
////class Base {
//// private privateMethod() { }
//// private privateProperty;
////
//// protected protectedMethod() { }
//// protected protectedProperty;
////
//// public publicMethod() { }
//// public publicProperty;
////
//// protected protectedOverriddenMethod() { }
//// protected protectedOverriddenProperty;
////}
////
////class C1 extends Base {
//// protected protectedOverriddenMethod() { }
//// protected protectedOverriddenProperty;
////
//// test() {
//// this./*1*/;
//// super./*2*/;
////
//// var b: Base;
//// var c: C1;
////
//// b./*3*/;
//// c./*4*/;
//// }
////}
// Same class, everything is visible
goTo.marker("1");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');
// Can not access properties on super
goTo.marker("2");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.not.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.not.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.not.memberListContains('protectedOverriddenProperty');
// Can not access protected properties through base class
goTo.marker("3");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.not.memberListContains('protectedMethod');
verify.not.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.not.memberListContains('protectedOverriddenMethod');
verify.not.memberListContains('protectedOverriddenProperty');
// Same class, everything is visible
goTo.marker("4");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');

View File

@ -0,0 +1,46 @@
/// <reference path='fourslash.ts'/>
////class Base {
//// private privateMethod() { }
//// private privateProperty;
////
//// protected protectedMethod() { }
//// protected protectedProperty;
////
//// public publicMethod() { }
//// public publicProperty;
////
//// protected protectedOverriddenMethod() { }
//// protected protectedOverriddenProperty;
////}
////
////class C1 extends Base {
//// protected protectedOverriddenMethod() { }
//// protected protectedOverriddenProperty;
////}
////
//// var b: Base;
//// var c: C1;
//// b./*1*/;
//// c./*2*/;
// Only public properties are visible outside the class
goTo.marker("1");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.not.memberListContains('protectedMethod');
verify.not.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.not.memberListContains('protectedOverriddenMethod');
verify.not.memberListContains('protectedOverriddenProperty');
goTo.marker("2");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.not.memberListContains('protectedMethod');
verify.not.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.not.memberListContains('protectedOverriddenMethod');
verify.not.memberListContains('protectedOverriddenProperty');

View File

@ -0,0 +1,34 @@
/// <reference path='fourslash.ts'/>
////class Base {
//// private privateMethod() { }
//// private privateProperty;
////
//// protected protectedMethod() { }
//// protected protectedProperty;
////
//// public publicMethod() { }
//// public publicProperty;
////
//// protected protectedOverriddenMethod() { }
//// protected protectedOverriddenProperty;
////}
////
////class C1 extends Base {
//// public protectedOverriddenMethod() { }
//// public protectedOverriddenProperty;
////}
////
//// var c: C1;
//// c./*1*/
goTo.marker("1");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.not.memberListContains('protectedMethod');
verify.not.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');

View File

@ -0,0 +1,44 @@
/// <reference path="fourslash.ts"/>
////class Base {
//// protected y;
//// constructor(protected x) {}
//// method() { this./*1*/; }
////}
////class D1 extends Base {
//// protected z;
//// method1() { this./*2*/; }
////}
////class D2 extends Base {
//// method2() { this./*3*/; }
////}
////class D3 extends D1 {
//// method2() { this./*4*/; }
////}
////var b: Base;
////f./*5*/
goTo.marker("1");
verify.memberListContains("y");
verify.memberListContains("x");
verify.not.memberListContains("z");
goTo.marker("2");
verify.memberListContains("y");
verify.memberListContains("x");
verify.memberListContains("z");
goTo.marker("3");
verify.memberListContains("y");
verify.memberListContains("x");
verify.not.memberListContains("z");
goTo.marker("4");
verify.memberListContains("y");
verify.memberListContains("x");
verify.memberListContains("z");
goTo.marker("5");
verify.not.memberListContains("x");
verify.not.memberListContains("y");
verify.not.memberListContains("z");

View File

@ -0,0 +1,59 @@
/// <reference path='fourslash.ts'/>
////class Base {
//// private static privateMethod() { }
//// private static privateProperty;
////
//// protected static protectedMethod() { }
//// protected static protectedProperty;
////
//// public static publicMethod() { }
//// public static publicProperty;
////
//// protected static protectedOverriddenMethod() { }
//// protected static protectedOverriddenProperty;
////
//// static test() {
//// Base./*1*/;
//// this./*2*/;
//// C1./*3*/;
//// }
////}
////
////class C1 extends Base {
//// protected static protectedOverriddenMethod() { }
//// protected static protectedOverriddenProperty;
////}
// Same class, everything is visible
goTo.marker("1");
verify.memberListContains('privateMethod');
verify.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');
goTo.marker("2");
verify.memberListContains('privateMethod');
verify.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');
// Can not access protected properties overridden in subclass
goTo.marker("3");
verify.memberListContains('privateMethod');
verify.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.not.memberListContains('protectedOverriddenMethod');
verify.not.memberListContains('protectedOverriddenProperty');

View File

@ -0,0 +1,70 @@
/// <reference path='fourslash.ts'/>
////class Base {
//// private static privateMethod() { }
//// private static privateProperty;
////
//// protected static protectedMethod() { }
//// protected static protectedProperty;
////
//// public static publicMethod() { }
//// public static publicProperty;
////
//// protected static protectedOverriddenMethod() { }
//// protected static protectedOverriddenProperty;
////}
////
////class C2 extends Base {
//// protected static protectedOverriddenMethod() { }
//// protected static protectedOverriddenProperty;
////
//// static test() {
//// Base./*1*/;
//// C2./*2*/;
//// this./*3*/;
//// super./*4*/;
//// }
////}
// Same class, everything is visible
goTo.marker("1");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');
goTo.marker("2");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');
goTo.marker("3");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');
// only public and protected methods of the base class are accessible through super
goTo.marker("4");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.not.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.not.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.not.memberListContains('protectedOverriddenProperty');

View File

@ -0,0 +1,45 @@
/// <reference path='fourslash.ts'/>
////class Base {
//// private static privateMethod() { }
//// private static privateProperty;
////
//// protected static protectedMethod() { }
//// protected static protectedProperty;
////
//// public static publicMethod() { }
//// public static publicProperty;
////
//// protected static protectedOverriddenMethod() { }
//// protected static protectedOverriddenProperty;
////}
////
////class C3 extends Base {
//// protected static protectedOverriddenMethod() { }
//// protected static protectedOverriddenProperty;
////}
////
////Base./*1*/;
////C3./*2*/;
// Only public properties are visible outside the class
goTo.marker("1");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.not.memberListContains('protectedMethod');
verify.not.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.not.memberListContains('protectedOverriddenMethod');
verify.not.memberListContains('protectedOverriddenProperty');
goTo.marker("2");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.not.memberListContains('protectedMethod');
verify.not.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.not.memberListContains('protectedOverriddenMethod');
verify.not.memberListContains('protectedOverriddenProperty');

View File

@ -0,0 +1,49 @@
/// <reference path='fourslash.ts'/>
////class Base {
//// private static privateMethod() { }
//// private static privateProperty;
////
//// protected static protectedMethod() { }
//// protected static protectedProperty;
////
//// public static publicMethod() { }
//// public static publicProperty;
////
//// protected static protectedOverriddenMethod() { }
//// protected static protectedOverriddenProperty;
////}
////
/////// Make the protected members public
////class C4 extends Base {
//// public static protectedOverriddenMethod() { }
//// public static protectedOverriddenProperty;
////}
////class Derived extends C4 {
//// test() {
//// Derived./*1*/
//// }
////}
//// Derived./*2*/
// Sub class, everything but private is visible
goTo.marker("1");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.memberListContains('protectedMethod');
verify.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');
// Can see protected methods elevated to public
goTo.marker("2");
verify.not.memberListContains('privateMethod');
verify.not.memberListContains('privateProperty');
verify.not.memberListContains('protectedMethod');
verify.not.memberListContains('protectedProperty');
verify.memberListContains('publicMethod');
verify.memberListContains('publicProperty');
verify.memberListContains('protectedOverriddenMethod');
verify.memberListContains('protectedOverriddenProperty');

View File

@ -25,7 +25,7 @@
goTo.marker();
verify.memberListContains("publicProperty");
verify.not.memberListContains("publicProperty");
verify.memberListContains("publicInstanceMethod");
// No statics
verify.not.memberListContains("publicStaticProperty");