From 15b4af63dd9985d23ebfa55dcbb70562708c73a7 Mon Sep 17 00:00:00 2001 From: Andrey Roenko Date: Fri, 12 Oct 2018 17:16:54 +0300 Subject: [PATCH] #27716: fix protected methods for intersection fo generic classes --- src/compiler/checker.ts | 14 +++- tests/baselines/reference/arraySlice.symbols | 4 +- .../reference/bivariantInferences.symbols | 4 +- .../reference/controlFlowArrayErrors.symbols | 4 +- .../reference/mixinAccessModifiers.errors.txt | 45 ++++++++++- .../reference/mixinAccessModifiers.js | 72 +++++++++++++++++ .../reference/mixinAccessModifiers.symbols | 79 +++++++++++++++++++ .../reference/mixinAccessModifiers.types | 77 ++++++++++++++++++ .../typeParameterExtendingUnion1.symbols | 4 +- .../typeParameterExtendingUnion2.symbols | 8 +- .../classes/mixinAccessModifiers.ts | 25 ++++++ tests/cases/fourslash/commentsUnion.ts | 2 +- .../completionEntryForUnionMethod.ts | 4 +- 13 files changed, 323 insertions(+), 19 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 62756388dc4..536b762c021 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7354,13 +7354,13 @@ namespace ts { const propTypes: Type[] = []; let first = true; let commonValueDeclaration: Declaration | undefined; - let hasNonUniformValueDeclaration = false; + let hasUniformValueDeclaration = true; for (const prop of props) { if (!commonValueDeclaration) { commonValueDeclaration = prop.valueDeclaration; } else if (prop.valueDeclaration !== commonValueDeclaration) { - hasNonUniformValueDeclaration = true; + hasUniformValueDeclaration = false; } declarations = addRange(declarations, prop.declarations); const type = getTypeOfSymbol(prop); @@ -7379,9 +7379,17 @@ namespace ts { addRange(propTypes, indexTypes); const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags); result.containingType = containingType; - if (!hasNonUniformValueDeclaration && commonValueDeclaration) { + + // All intersections lead to the same value declaration. + if (hasUniformValueDeclaration && commonValueDeclaration) { result.valueDeclaration = commonValueDeclaration; + + // Inherit information about parent type. + if (commonValueDeclaration.symbol.parent) { + result.parent = commonValueDeclaration.symbol.parent; + } } + result.declarations = declarations!; result.nameType = nameType; result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes); diff --git a/tests/baselines/reference/arraySlice.symbols b/tests/baselines/reference/arraySlice.symbols index a603a39c254..2ba96cbb582 100644 --- a/tests/baselines/reference/arraySlice.symbols +++ b/tests/baselines/reference/arraySlice.symbols @@ -3,7 +3,7 @@ var arr: string[] | number[]; >arr : Symbol(arr, Decl(arraySlice.ts, 0, 3)) arr.splice(1, 1); ->arr.splice : Symbol(splice, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>arr.splice : Symbol(Array.splice, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >arr : Symbol(arr, Decl(arraySlice.ts, 0, 3)) ->splice : Symbol(splice, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>splice : Symbol(Array.splice, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) diff --git a/tests/baselines/reference/bivariantInferences.symbols b/tests/baselines/reference/bivariantInferences.symbols index 63cc239f040..0697c171c54 100644 --- a/tests/baselines/reference/bivariantInferences.symbols +++ b/tests/baselines/reference/bivariantInferences.symbols @@ -24,8 +24,8 @@ declare const b: (string | number)[] | null[] | undefined[] | {}[]; let x = a.equalsShallow(b); >x : Symbol(x, Decl(bivariantInferences.ts, 9, 3)) ->a.equalsShallow : Symbol(equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20)) +>a.equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20)) >a : Symbol(a, Decl(bivariantInferences.ts, 6, 13)) ->equalsShallow : Symbol(equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20)) +>equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20)) >b : Symbol(b, Decl(bivariantInferences.ts, 7, 13)) diff --git a/tests/baselines/reference/controlFlowArrayErrors.symbols b/tests/baselines/reference/controlFlowArrayErrors.symbols index 46a61f13e43..99766693e0c 100644 --- a/tests/baselines/reference/controlFlowArrayErrors.symbols +++ b/tests/baselines/reference/controlFlowArrayErrors.symbols @@ -121,9 +121,9 @@ function f6() { >x : Symbol(x, Decl(controlFlowArrayErrors.ts, 37, 7)) x.push(99); // Error ->x.push : Symbol(push, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>x.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >x : Symbol(x, Decl(controlFlowArrayErrors.ts, 37, 7)) ->push : Symbol(push, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) } function f7() { diff --git a/tests/baselines/reference/mixinAccessModifiers.errors.txt b/tests/baselines/reference/mixinAccessModifiers.errors.txt index fa2fc4ac99a..05cd72cbb6b 100644 --- a/tests/baselines/reference/mixinAccessModifiers.errors.txt +++ b/tests/baselines/reference/mixinAccessModifiers.errors.txt @@ -15,9 +15,15 @@ tests/cases/conformance/classes/mixinAccessModifiers.ts(84,6): error TS2445: Pro tests/cases/conformance/classes/mixinAccessModifiers.ts(89,6): error TS2445: Property 's' is protected and only accessible within class 'typeof C4' and its subclasses. tests/cases/conformance/classes/mixinAccessModifiers.ts(97,6): error TS2445: Property 'p' is protected and only accessible within class 'C4' and its subclasses. tests/cases/conformance/classes/mixinAccessModifiers.ts(102,6): error TS2445: Property 's' is protected and only accessible within class 'typeof C4' and its subclasses. +tests/cases/conformance/classes/mixinAccessModifiers.ts(119,4): error TS2341: Property 'privateMethod' is private and only accessible within class 'ProtectedGeneric'. +tests/cases/conformance/classes/mixinAccessModifiers.ts(120,4): error TS2445: Property 'protectedMethod' is protected and only accessible within class 'ProtectedGeneric' and its subclasses. +tests/cases/conformance/classes/mixinAccessModifiers.ts(124,4): error TS2546: Property 'privateMethod' has conflicting declarations and is inaccessible in type 'ProtectedGeneric<{ a: void; }> & ProtectedGeneric2<{ a: void; b: void; }>'. +tests/cases/conformance/classes/mixinAccessModifiers.ts(125,4): error TS2445: Property 'protectedMethod' is protected and only accessible within class 'ProtectedGeneric<{ a: void; }> & ProtectedGeneric2<{ a: void; b: void; }>' and its subclasses. +tests/cases/conformance/classes/mixinAccessModifiers.ts(129,4): error TS2546: Property 'privateMethod' has conflicting declarations and is inaccessible in type 'ProtectedGeneric<{ a: void; }> & ProtectedGeneric<{ a: void; b: void; }>'. +tests/cases/conformance/classes/mixinAccessModifiers.ts(130,4): error TS2445: Property 'protectedMethod' is protected and only accessible within class 'ProtectedGeneric' and its subclasses. -==== tests/cases/conformance/classes/mixinAccessModifiers.ts (11 errors) ==== +==== tests/cases/conformance/classes/mixinAccessModifiers.ts (17 errors) ==== type Constructable = new (...args: any[]) => object; class Private { @@ -152,4 +158,41 @@ tests/cases/conformance/classes/mixinAccessModifiers.ts(102,6): error TS2445: Pr C6.s } } + + class ProtectedGeneric { + private privateMethod() {} + protected protectedMethod() {} + } + + class ProtectedGeneric2 { + private privateMethod() {} + protected protectedMethod() {} + } + + function f7(x: ProtectedGeneric<{}> & ProtectedGeneric<{}>) { + x.privateMethod(); // Error, private constituent makes method inaccessible + ~~~~~~~~~~~~~ +!!! error TS2341: Property 'privateMethod' is private and only accessible within class 'ProtectedGeneric'. + x.protectedMethod(); // Error, protected when all constituents are protected + ~~~~~~~~~~~~~~~ +!!! error TS2445: Property 'protectedMethod' is protected and only accessible within class 'ProtectedGeneric' and its subclasses. + } + + function f8(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric2<{a:void;b:void;}>) { + x.privateMethod(); // Error, private constituent makes method inaccessible + ~~~~~~~~~~~~~ +!!! error TS2546: Property 'privateMethod' has conflicting declarations and is inaccessible in type 'ProtectedGeneric<{ a: void; }> & ProtectedGeneric2<{ a: void; b: void; }>'. + x.protectedMethod(); // Error, protected when all constituents are protected + ~~~~~~~~~~~~~~~ +!!! error TS2445: Property 'protectedMethod' is protected and only accessible within class 'ProtectedGeneric<{ a: void; }> & ProtectedGeneric2<{ a: void; b: void; }>' and its subclasses. + } + + function f9(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric<{a:void;b:void;}>) { + x.privateMethod(); // Error, private constituent makes method inaccessible + ~~~~~~~~~~~~~ +!!! error TS2546: Property 'privateMethod' has conflicting declarations and is inaccessible in type 'ProtectedGeneric<{ a: void; }> & ProtectedGeneric<{ a: void; b: void; }>'. + x.protectedMethod(); // Error, protected when all constituents are protected + ~~~~~~~~~~~~~~~ +!!! error TS2445: Property 'protectedMethod' is protected and only accessible within class 'ProtectedGeneric' and its subclasses. + } \ No newline at end of file diff --git a/tests/baselines/reference/mixinAccessModifiers.js b/tests/baselines/reference/mixinAccessModifiers.js index ef2cc258dd7..2d158f6841e 100644 --- a/tests/baselines/reference/mixinAccessModifiers.js +++ b/tests/baselines/reference/mixinAccessModifiers.js @@ -105,6 +105,31 @@ class C6 extends Mix(Public, Public2) { C6.s } } + +class ProtectedGeneric { + private privateMethod() {} + protected protectedMethod() {} +} + +class ProtectedGeneric2 { + private privateMethod() {} + protected protectedMethod() {} +} + +function f7(x: ProtectedGeneric<{}> & ProtectedGeneric<{}>) { + x.privateMethod(); // Error, private constituent makes method inaccessible + x.protectedMethod(); // Error, protected when all constituents are protected +} + +function f8(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric2<{a:void;b:void;}>) { + x.privateMethod(); // Error, private constituent makes method inaccessible + x.protectedMethod(); // Error, protected when all constituents are protected +} + +function f9(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric<{a:void;b:void;}>) { + x.privateMethod(); // Error, private constituent makes method inaccessible + x.protectedMethod(); // Error, protected when all constituents are protected +} //// [mixinAccessModifiers.js] @@ -266,6 +291,32 @@ var C6 = /** @class */ (function (_super) { }; return C6; }(Mix(Public, Public2))); +var ProtectedGeneric = /** @class */ (function () { + function ProtectedGeneric() { + } + ProtectedGeneric.prototype.privateMethod = function () { }; + ProtectedGeneric.prototype.protectedMethod = function () { }; + return ProtectedGeneric; +}()); +var ProtectedGeneric2 = /** @class */ (function () { + function ProtectedGeneric2() { + } + ProtectedGeneric2.prototype.privateMethod = function () { }; + ProtectedGeneric2.prototype.protectedMethod = function () { }; + return ProtectedGeneric2; +}()); +function f7(x) { + x.privateMethod(); // Error, private constituent makes method inaccessible + x.protectedMethod(); // Error, protected when all constituents are protected +} +function f8(x) { + x.privateMethod(); // Error, private constituent makes method inaccessible + x.protectedMethod(); // Error, protected when all constituents are protected +} +function f9(x) { + x.privateMethod(); // Error, private constituent makes method inaccessible + x.protectedMethod(); // Error, protected when all constituents are protected +} //// [mixinAccessModifiers.d.ts] @@ -329,3 +380,24 @@ declare class C6 extends C6_base { f(c4: C4, c5: C5, c6: C6): void; static g(): void; } +declare class ProtectedGeneric { + private privateMethod; + protected protectedMethod(): void; +} +declare class ProtectedGeneric2 { + private privateMethod; + protected protectedMethod(): void; +} +declare function f7(x: ProtectedGeneric<{}> & ProtectedGeneric<{}>): void; +declare function f8(x: ProtectedGeneric<{ + a: void; +}> & ProtectedGeneric2<{ + a: void; + b: void; +}>): void; +declare function f9(x: ProtectedGeneric<{ + a: void; +}> & ProtectedGeneric<{ + a: void; + b: void; +}>): void; diff --git a/tests/baselines/reference/mixinAccessModifiers.symbols b/tests/baselines/reference/mixinAccessModifiers.symbols index f9dd12cdd64..e0186264f93 100644 --- a/tests/baselines/reference/mixinAccessModifiers.symbols +++ b/tests/baselines/reference/mixinAccessModifiers.symbols @@ -328,3 +328,82 @@ class C6 extends Mix(Public, Public2) { } } +class ProtectedGeneric { +>ProtectedGeneric : Symbol(ProtectedGeneric, Decl(mixinAccessModifiers.ts, 105, 1)) +>T : Symbol(T, Decl(mixinAccessModifiers.ts, 107, 23)) + + private privateMethod() {} +>privateMethod : Symbol(ProtectedGeneric.privateMethod, Decl(mixinAccessModifiers.ts, 107, 27)) + + protected protectedMethod() {} +>protectedMethod : Symbol(ProtectedGeneric.protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27)) +} + +class ProtectedGeneric2 { +>ProtectedGeneric2 : Symbol(ProtectedGeneric2, Decl(mixinAccessModifiers.ts, 110, 1)) +>T : Symbol(T, Decl(mixinAccessModifiers.ts, 112, 24)) + + private privateMethod() {} +>privateMethod : Symbol(ProtectedGeneric2.privateMethod, Decl(mixinAccessModifiers.ts, 112, 28)) + + protected protectedMethod() {} +>protectedMethod : Symbol(ProtectedGeneric2.protectedMethod, Decl(mixinAccessModifiers.ts, 113, 27)) +} + +function f7(x: ProtectedGeneric<{}> & ProtectedGeneric<{}>) { +>f7 : Symbol(f7, Decl(mixinAccessModifiers.ts, 115, 1)) +>x : Symbol(x, Decl(mixinAccessModifiers.ts, 117, 12)) +>ProtectedGeneric : Symbol(ProtectedGeneric, Decl(mixinAccessModifiers.ts, 105, 1)) +>ProtectedGeneric : Symbol(ProtectedGeneric, Decl(mixinAccessModifiers.ts, 105, 1)) + + x.privateMethod(); // Error, private constituent makes method inaccessible +>x.privateMethod : Symbol(ProtectedGeneric.privateMethod, Decl(mixinAccessModifiers.ts, 107, 27)) +>x : Symbol(x, Decl(mixinAccessModifiers.ts, 117, 12)) +>privateMethod : Symbol(ProtectedGeneric.privateMethod, Decl(mixinAccessModifiers.ts, 107, 27)) + + x.protectedMethod(); // Error, protected when all constituents are protected +>x.protectedMethod : Symbol(ProtectedGeneric.protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27)) +>x : Symbol(x, Decl(mixinAccessModifiers.ts, 117, 12)) +>protectedMethod : Symbol(ProtectedGeneric.protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27)) +} + +function f8(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric2<{a:void;b:void;}>) { +>f8 : Symbol(f8, Decl(mixinAccessModifiers.ts, 120, 1)) +>x : Symbol(x, Decl(mixinAccessModifiers.ts, 122, 12)) +>ProtectedGeneric : Symbol(ProtectedGeneric, Decl(mixinAccessModifiers.ts, 105, 1)) +>a : Symbol(a, Decl(mixinAccessModifiers.ts, 122, 33)) +>ProtectedGeneric2 : Symbol(ProtectedGeneric2, Decl(mixinAccessModifiers.ts, 110, 1)) +>a : Symbol(a, Decl(mixinAccessModifiers.ts, 122, 65)) +>b : Symbol(b, Decl(mixinAccessModifiers.ts, 122, 72)) + + x.privateMethod(); // Error, private constituent makes method inaccessible +>x.privateMethod : Symbol(privateMethod, Decl(mixinAccessModifiers.ts, 107, 27), Decl(mixinAccessModifiers.ts, 112, 28)) +>x : Symbol(x, Decl(mixinAccessModifiers.ts, 122, 12)) +>privateMethod : Symbol(privateMethod, Decl(mixinAccessModifiers.ts, 107, 27), Decl(mixinAccessModifiers.ts, 112, 28)) + + x.protectedMethod(); // Error, protected when all constituents are protected +>x.protectedMethod : Symbol(protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27), Decl(mixinAccessModifiers.ts, 113, 27)) +>x : Symbol(x, Decl(mixinAccessModifiers.ts, 122, 12)) +>protectedMethod : Symbol(protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27), Decl(mixinAccessModifiers.ts, 113, 27)) +} + +function f9(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric<{a:void;b:void;}>) { +>f9 : Symbol(f9, Decl(mixinAccessModifiers.ts, 125, 1)) +>x : Symbol(x, Decl(mixinAccessModifiers.ts, 127, 12)) +>ProtectedGeneric : Symbol(ProtectedGeneric, Decl(mixinAccessModifiers.ts, 105, 1)) +>a : Symbol(a, Decl(mixinAccessModifiers.ts, 127, 33)) +>ProtectedGeneric : Symbol(ProtectedGeneric, Decl(mixinAccessModifiers.ts, 105, 1)) +>a : Symbol(a, Decl(mixinAccessModifiers.ts, 127, 64)) +>b : Symbol(b, Decl(mixinAccessModifiers.ts, 127, 71)) + + x.privateMethod(); // Error, private constituent makes method inaccessible +>x.privateMethod : Symbol(ProtectedGeneric.privateMethod, Decl(mixinAccessModifiers.ts, 107, 27), Decl(mixinAccessModifiers.ts, 107, 27)) +>x : Symbol(x, Decl(mixinAccessModifiers.ts, 127, 12)) +>privateMethod : Symbol(ProtectedGeneric.privateMethod, Decl(mixinAccessModifiers.ts, 107, 27), Decl(mixinAccessModifiers.ts, 107, 27)) + + x.protectedMethod(); // Error, protected when all constituents are protected +>x.protectedMethod : Symbol(ProtectedGeneric.protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27), Decl(mixinAccessModifiers.ts, 108, 27)) +>x : Symbol(x, Decl(mixinAccessModifiers.ts, 127, 12)) +>protectedMethod : Symbol(ProtectedGeneric.protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27), Decl(mixinAccessModifiers.ts, 108, 27)) +} + diff --git a/tests/baselines/reference/mixinAccessModifiers.types b/tests/baselines/reference/mixinAccessModifiers.types index 98b930f820c..ffa7b2b1e71 100644 --- a/tests/baselines/reference/mixinAccessModifiers.types +++ b/tests/baselines/reference/mixinAccessModifiers.types @@ -307,3 +307,80 @@ class C6 extends Mix(Public, Public2) { } } +class ProtectedGeneric { +>ProtectedGeneric : ProtectedGeneric + + private privateMethod() {} +>privateMethod : () => void + + protected protectedMethod() {} +>protectedMethod : () => void +} + +class ProtectedGeneric2 { +>ProtectedGeneric2 : ProtectedGeneric2 + + private privateMethod() {} +>privateMethod : () => void + + protected protectedMethod() {} +>protectedMethod : () => void +} + +function f7(x: ProtectedGeneric<{}> & ProtectedGeneric<{}>) { +>f7 : (x: ProtectedGeneric<{}>) => void +>x : ProtectedGeneric<{}> + + x.privateMethod(); // Error, private constituent makes method inaccessible +>x.privateMethod() : void +>x.privateMethod : () => void +>x : ProtectedGeneric<{}> +>privateMethod : () => void + + x.protectedMethod(); // Error, protected when all constituents are protected +>x.protectedMethod() : void +>x.protectedMethod : () => void +>x : ProtectedGeneric<{}> +>protectedMethod : () => void +} + +function f8(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric2<{a:void;b:void;}>) { +>f8 : (x: ProtectedGeneric<{ a: void; }> & ProtectedGeneric2<{ a: void; b: void; }>) => void +>x : ProtectedGeneric<{ a: void; }> & ProtectedGeneric2<{ a: void; b: void; }> +>a : void +>a : void +>b : void + + x.privateMethod(); // Error, private constituent makes method inaccessible +>x.privateMethod() : void +>x.privateMethod : (() => void) & (() => void) +>x : ProtectedGeneric<{ a: void; }> & ProtectedGeneric2<{ a: void; b: void; }> +>privateMethod : (() => void) & (() => void) + + x.protectedMethod(); // Error, protected when all constituents are protected +>x.protectedMethod() : void +>x.protectedMethod : (() => void) & (() => void) +>x : ProtectedGeneric<{ a: void; }> & ProtectedGeneric2<{ a: void; b: void; }> +>protectedMethod : (() => void) & (() => void) +} + +function f9(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric<{a:void;b:void;}>) { +>f9 : (x: ProtectedGeneric<{ a: void; }> & ProtectedGeneric<{ a: void; b: void; }>) => void +>x : ProtectedGeneric<{ a: void; }> & ProtectedGeneric<{ a: void; b: void; }> +>a : void +>a : void +>b : void + + x.privateMethod(); // Error, private constituent makes method inaccessible +>x.privateMethod() : void +>x.privateMethod : (() => void) & (() => void) +>x : ProtectedGeneric<{ a: void; }> & ProtectedGeneric<{ a: void; b: void; }> +>privateMethod : (() => void) & (() => void) + + x.protectedMethod(); // Error, protected when all constituents are protected +>x.protectedMethod() : void +>x.protectedMethod : (() => void) & (() => void) +>x : ProtectedGeneric<{ a: void; }> & ProtectedGeneric<{ a: void; b: void; }> +>protectedMethod : (() => void) & (() => void) +} + diff --git a/tests/baselines/reference/typeParameterExtendingUnion1.symbols b/tests/baselines/reference/typeParameterExtendingUnion1.symbols index 0538dcf91e0..cb36861feba 100644 --- a/tests/baselines/reference/typeParameterExtendingUnion1.symbols +++ b/tests/baselines/reference/typeParameterExtendingUnion1.symbols @@ -33,9 +33,9 @@ function f(a: T) { >T : Symbol(T, Decl(typeParameterExtendingUnion1.ts, 8, 11)) a.run(); ->a.run : Symbol(run, Decl(typeParameterExtendingUnion1.ts, 0, 14), Decl(typeParameterExtendingUnion1.ts, 0, 14)) +>a.run : Symbol(Animal.run, Decl(typeParameterExtendingUnion1.ts, 0, 14), Decl(typeParameterExtendingUnion1.ts, 0, 14)) >a : Symbol(a, Decl(typeParameterExtendingUnion1.ts, 8, 32)) ->run : Symbol(run, Decl(typeParameterExtendingUnion1.ts, 0, 14), Decl(typeParameterExtendingUnion1.ts, 0, 14)) +>run : Symbol(Animal.run, Decl(typeParameterExtendingUnion1.ts, 0, 14), Decl(typeParameterExtendingUnion1.ts, 0, 14)) run(a); >run : Symbol(run, Decl(typeParameterExtendingUnion1.ts, 2, 33)) diff --git a/tests/baselines/reference/typeParameterExtendingUnion2.symbols b/tests/baselines/reference/typeParameterExtendingUnion2.symbols index f29f12f6f09..b9c2eed4034 100644 --- a/tests/baselines/reference/typeParameterExtendingUnion2.symbols +++ b/tests/baselines/reference/typeParameterExtendingUnion2.symbols @@ -20,9 +20,9 @@ function run(a: Cat | Dog) { >Dog : Symbol(Dog, Decl(typeParameterExtendingUnion2.ts, 1, 33)) a.run(); ->a.run : Symbol(run, Decl(typeParameterExtendingUnion2.ts, 0, 14), Decl(typeParameterExtendingUnion2.ts, 0, 14)) +>a.run : Symbol(Animal.run, Decl(typeParameterExtendingUnion2.ts, 0, 14), Decl(typeParameterExtendingUnion2.ts, 0, 14)) >a : Symbol(a, Decl(typeParameterExtendingUnion2.ts, 4, 13)) ->run : Symbol(run, Decl(typeParameterExtendingUnion2.ts, 0, 14), Decl(typeParameterExtendingUnion2.ts, 0, 14)) +>run : Symbol(Animal.run, Decl(typeParameterExtendingUnion2.ts, 0, 14), Decl(typeParameterExtendingUnion2.ts, 0, 14)) } function f(a: T) { @@ -34,9 +34,9 @@ function f(a: T) { >T : Symbol(T, Decl(typeParameterExtendingUnion2.ts, 8, 11)) a.run(); ->a.run : Symbol(run, Decl(typeParameterExtendingUnion2.ts, 0, 14), Decl(typeParameterExtendingUnion2.ts, 0, 14)) +>a.run : Symbol(Animal.run, Decl(typeParameterExtendingUnion2.ts, 0, 14), Decl(typeParameterExtendingUnion2.ts, 0, 14)) >a : Symbol(a, Decl(typeParameterExtendingUnion2.ts, 8, 32)) ->run : Symbol(run, Decl(typeParameterExtendingUnion2.ts, 0, 14), Decl(typeParameterExtendingUnion2.ts, 0, 14)) +>run : Symbol(Animal.run, Decl(typeParameterExtendingUnion2.ts, 0, 14), Decl(typeParameterExtendingUnion2.ts, 0, 14)) run(a); >run : Symbol(run, Decl(typeParameterExtendingUnion2.ts, 2, 33)) diff --git a/tests/cases/conformance/classes/mixinAccessModifiers.ts b/tests/cases/conformance/classes/mixinAccessModifiers.ts index a628371eec6..554d8b6a312 100644 --- a/tests/cases/conformance/classes/mixinAccessModifiers.ts +++ b/tests/cases/conformance/classes/mixinAccessModifiers.ts @@ -106,3 +106,28 @@ class C6 extends Mix(Public, Public2) { C6.s } } + +class ProtectedGeneric { + private privateMethod() {} + protected protectedMethod() {} +} + +class ProtectedGeneric2 { + private privateMethod() {} + protected protectedMethod() {} +} + +function f7(x: ProtectedGeneric<{}> & ProtectedGeneric<{}>) { + x.privateMethod(); // Error, private constituent makes method inaccessible + x.protectedMethod(); // Error, protected when all constituents are protected +} + +function f8(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric2<{a:void;b:void;}>) { + x.privateMethod(); // Error, private constituent makes method inaccessible + x.protectedMethod(); // Error, protected when all constituents are protected +} + +function f9(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric<{a:void;b:void;}>) { + x.privateMethod(); // Error, private constituent makes method inaccessible + x.protectedMethod(); // Error, protected when all constituents are protected +} diff --git a/tests/cases/fourslash/commentsUnion.ts b/tests/cases/fourslash/commentsUnion.ts index a54eaf076d7..616da3ea9d2 100644 --- a/tests/cases/fourslash/commentsUnion.ts +++ b/tests/cases/fourslash/commentsUnion.ts @@ -3,4 +3,4 @@ ////var a: Array | Array; ////a./*1*/length -verify.quickInfoAt("1", "(property) length: number", "Gets or sets the length of the array. This is a number one higher than the highest element defined in an array."); \ No newline at end of file +verify.quickInfoAt("1", "(property) Array.length: number", "Gets or sets the length of the array. This is a number one higher than the highest element defined in an array."); \ No newline at end of file diff --git a/tests/cases/fourslash/completionEntryForUnionMethod.ts b/tests/cases/fourslash/completionEntryForUnionMethod.ts index f8fd9ad9dc9..4daf989d314 100644 --- a/tests/cases/fourslash/completionEntryForUnionMethod.ts +++ b/tests/cases/fourslash/completionEntryForUnionMethod.ts @@ -5,7 +5,7 @@ goTo.marker(); verify.quickInfoIs( - "(property) map: ((callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]) | ((callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[])", + "(property) Array.map: ((callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]) | ((callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[])", "Calls a defined callback function on each element of an array, and returns an array that contains the results."); -verify.completionListContains('map', "(property) map: ((callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]) | ((callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[])"); \ No newline at end of file +verify.completionListContains('map', "(property) Array.map: ((callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]) | ((callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[])"); \ No newline at end of file