From 8cebdcc758ff7b96869423598249461b65bf2b37 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 22 Dec 2015 19:29:49 -0800 Subject: [PATCH 1/9] Add tests for find-all-references --- .../referencesForInheritedProperties3.ts | 15 +++++++ .../referencesForInheritedProperties4.ts | 15 +++++++ .../referencesForInheritedProperties5.ts | 19 +++++++++ .../referencesForInheritedProperties6.ts | 32 ++++++++++++++ .../referencesForInheritedProperties7.ts | 42 +++++++++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 tests/cases/fourslash/referencesForInheritedProperties3.ts create mode 100644 tests/cases/fourslash/referencesForInheritedProperties4.ts create mode 100644 tests/cases/fourslash/referencesForInheritedProperties5.ts create mode 100644 tests/cases/fourslash/referencesForInheritedProperties6.ts create mode 100644 tests/cases/fourslash/referencesForInheritedProperties7.ts diff --git a/tests/cases/fourslash/referencesForInheritedProperties3.ts b/tests/cases/fourslash/referencesForInheritedProperties3.ts new file mode 100644 index 00000000000..134f75da84b --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties3.ts @@ -0,0 +1,15 @@ +/// + +//// interface interface1 extends interface1 { +//// /*1*/doStuff(): void; +//// /*2*/propName: string; +//// } +//// +//// var v: interface1; +//// v./*3*/propName; +//// v./*4*/doStuff(); + +test.markers().forEach(m => { + goTo.position(m.position, m.fileName); + verify.referencesCountIs(2); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties4.ts b/tests/cases/fourslash/referencesForInheritedProperties4.ts new file mode 100644 index 00000000000..10dcc9c77a2 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties4.ts @@ -0,0 +1,15 @@ +/// + +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } +//// +//// var c: class1; +//// c./*3*/doStuff(); +//// c./*4*/propName; + +test.markers().forEach(m => { + goTo.position(m.position, m.fileName); + verify.referencesCountIs(2); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties5.ts b/tests/cases/fourslash/referencesForInheritedProperties5.ts new file mode 100644 index 00000000000..722c5c96f0a --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties5.ts @@ -0,0 +1,19 @@ +/// + +//// interface interface1 extends interface1 { +//// /*1*/doStuff(): void; +//// /*2*/propName: string; +//// } +//// interface interface2 extends interface1 { +//// /*3*/doStuff(): void; +//// /*4*/propName: string; +//// } +//// +//// var v: interface1; +//// v./*5*/propName; +//// v./*6*/doStuff(); + +test.markers().forEach(m => { + goTo.position(m.position, m.fileName); + verify.referencesCountIs(3); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties6.ts b/tests/cases/fourslash/referencesForInheritedProperties6.ts new file mode 100644 index 00000000000..de6a2f2eba1 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties6.ts @@ -0,0 +1,32 @@ +/// + +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } +//// class class2 extends class1 { +//// /*3*/doStuff() { } +//// /*4*/propName: string; +//// } +//// +//// var v: class2; +//// v./*5*/propName; +//// v./*6*/doStuff(); + +goTo.marker("1"); +verify.referencesCountIs(1); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(2); + +goTo.marker("4"); +verify.referencesCountIs(3); + +goTo.marker("5"); +verify.referencesCountIs(3); + +goTo.marker("6"); +verify.referencesCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties7.ts b/tests/cases/fourslash/referencesForInheritedProperties7.ts new file mode 100644 index 00000000000..000d4922222 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties7.ts @@ -0,0 +1,42 @@ +/// + +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } +//// interface interface1 extends interface1 { +//// /*3*/doStuff(): void; +//// /*4*/propName: string; +//// } +//// class class2 extends class1 implements interface1 { +//// /*5*/doStuff() { } +//// /*6*/propName: string; +//// } +//// +//// var v: class2; +//// v./*7*/propName; +//// v./*8*/doStuff(); + +goTo.marker("1"); +verify.referencesCountIs(1); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(3); + +goTo.marker("4"); +verify.referencesCountIs(3); + +goTo.marker("5"); +verify.referencesCountIs(3); + +goTo.marker("6"); +verify.referencesCountIs(4); + +goTo.marker("7"); +verify.referencesCountIs(4); + +goTo.marker("8"); +verify.referencesCountIs(3); \ No newline at end of file From 05e5516fc0cd34bbe39f7e2607cffc8e9d63ef26 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 22 Dec 2015 20:02:42 -0800 Subject: [PATCH 2/9] Add rename tests --- .../cases/fourslash/renameInheritedProperties1.ts | 15 +++++++++++++++ .../cases/fourslash/renameInheritedProperties2.ts | 15 +++++++++++++++ .../cases/fourslash/renameInheritedProperties3.ts | 15 +++++++++++++++ .../cases/fourslash/renameInheritedProperties4.ts | 15 +++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 tests/cases/fourslash/renameInheritedProperties1.ts create mode 100644 tests/cases/fourslash/renameInheritedProperties2.ts create mode 100644 tests/cases/fourslash/renameInheritedProperties3.ts create mode 100644 tests/cases/fourslash/renameInheritedProperties4.ts diff --git a/tests/cases/fourslash/renameInheritedProperties1.ts b/tests/cases/fourslash/renameInheritedProperties1.ts new file mode 100644 index 00000000000..f0b2acf3b14 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties1.ts @@ -0,0 +1,15 @@ +/// + +//// class class1 extends class1 { +//// [|propName|]: string; +//// } +//// +//// var v: class1; +//// v.[|propName|]; + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties2.ts b/tests/cases/fourslash/renameInheritedProperties2.ts new file mode 100644 index 00000000000..ed99ec3e013 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties2.ts @@ -0,0 +1,15 @@ +/// + +//// class class1 extends class1 { +//// [|doStuff|]() { } +//// } +//// +//// var v: class1; +//// v.[|doStuff|](); + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties3.ts b/tests/cases/fourslash/renameInheritedProperties3.ts new file mode 100644 index 00000000000..17e7785fbc7 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties3.ts @@ -0,0 +1,15 @@ +/// + +//// interface interface1 extends interface1 { +//// [|propName|]: string; +//// } +//// +//// var v: interface1; +//// v.[|propName|]; + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties4.ts b/tests/cases/fourslash/renameInheritedProperties4.ts new file mode 100644 index 00000000000..ea2f7c40fbf --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties4.ts @@ -0,0 +1,15 @@ +/// + +//// interface interface1 extends interface1 { +//// [|doStuff|](): string; +//// } +//// +//// var v: interface1; +//// v.[|doStuff|](); + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file From 0682a63979b3a8dc66c1c546f16f2ef34a38050d Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 22 Dec 2015 20:26:54 -0800 Subject: [PATCH 3/9] Add find-all-references tests --- .../findAllRefsInheritedProperties1.ts | 25 +++++++++++++ .../findAllRefsInheritedProperties2.ts | 25 +++++++++++++ .../findAllRefsInheritedProperties3.ts | 37 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 tests/cases/fourslash/findAllRefsInheritedProperties1.ts create mode 100644 tests/cases/fourslash/findAllRefsInheritedProperties2.ts create mode 100644 tests/cases/fourslash/findAllRefsInheritedProperties3.ts diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts new file mode 100644 index 00000000000..b2755923d37 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts @@ -0,0 +1,25 @@ +/// + +//// class class1 extends class1 { +//// [|doStuff|]() { } +//// [|propName|]: string; +//// } +//// +//// var v: class1; +//// v.[|doStuff|](); +//// v.[|propName|]; + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3] = ranges; +verifyReferences(r0, [r0, r2]); +verifyReferences(r1, [r1, r3]); +verifyReferences(r2, [r0, r2]); +verifyReferences(r3, [r1, r3]); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties2.ts b/tests/cases/fourslash/findAllRefsInheritedProperties2.ts new file mode 100644 index 00000000000..1ab92c251da --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties2.ts @@ -0,0 +1,25 @@ +/// + +//// interface interface1 extends interface1 { +//// [|doStuff|](): void; // r0 +//// [|propName|]: string; // r1 +//// } +//// +//// var v: interface1; +//// v.[|doStuff|](); // r2 +//// v.[|propName|]; // r3 + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3] = ranges; +verifyReferences(r0, [r0, r2]); +verifyReferences(r1, [r1, r3]); +verifyReferences(r2, [r0, r2]); +verifyReferences(r3, [r1, r3]); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts new file mode 100644 index 00000000000..9a46b08f357 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts @@ -0,0 +1,37 @@ +/// + +//// class class1 extends class1 { +//// [|doStuff|]() { } // r0 +//// [|propName|]: string; // r1 +//// } +//// interface interface1 extends interface1 { +//// [|doStuff|](): void; // r2 +//// [|propName|]: string; // r3 +//// } +//// class class2 extends class1 implements interface1 { +//// [|doStuff|]() { } // r4 +//// [|propName|]: string; // r5 +//// } +//// +//// var v: class2; +//// v.[|propName|]; // r6 +//// v.[|doStuff|](); // r7 + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3, r4, r5, r6, r7] = ranges; +verifyReferences(r0, [r0]); +verifyReferences(r1, [r1, r5, r6]); +verifyReferences(r2, [r2, r4, r7]); +verifyReferences(r3, [r3, r5, r6]); +verifyReferences(r4, [r2, r4, r7]); +verifyReferences(r5, [r1, r3, r5, r6]); +verifyReferences(r6, [r1, r3, r5, r6]); +verifyReferences(r7, [r2, r4, r7]); \ No newline at end of file From 9534541829c0609188885f81d24cadc9a09396bf Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 22 Dec 2015 20:35:28 -0800 Subject: [PATCH 4/9] Add documenthightlight tests --- .../documentHighlightAtInheritedProperties1.ts | 13 +++++++++++++ .../documentHighlightAtInheritedProperties2.ts | 13 +++++++++++++ .../documentHighlightAtInheritedProperties3.ts | 17 +++++++++++++++++ .../documentHighlightAtInheritedProperties4.ts | 17 +++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts create mode 100644 tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts create mode 100644 tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts create mode 100644 tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts new file mode 100644 index 00000000000..23f6445a004 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts @@ -0,0 +1,13 @@ +/// + +// @Filename: file1.ts +//// interface interface1 extends interface1 { +//// /*1*/doStuff(): void; +//// /*2*/propName: string; +//// } + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); +} diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts new file mode 100644 index 00000000000..d4aadf96ed6 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts @@ -0,0 +1,13 @@ +/// + +// @Filename: file1.ts +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); +} \ No newline at end of file diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts new file mode 100644 index 00000000000..5e94bb387cd --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts @@ -0,0 +1,17 @@ +/// + +// @Filename: file1.ts +//// interface interface1 extends interface1 { +//// /*1*/doStuff(): void; +//// /*2*/propName: string; +//// } +//// +//// var v: interface1; +//// v./*3*/propName; +//// v./*4*/doStuff(); + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); +} diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts new file mode 100644 index 00000000000..50f459ebfdb --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts @@ -0,0 +1,17 @@ +/// + +// @Filename: file1.ts +//// class class1 extends class1 { +//// /*1*/doStuff() { } +//// /*2*/propName: string; +//// } +//// +//// var c: class1; +//// c./*3*/doStuff(); +//// c./*4*/propName; + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); +} From 5544fc0d85b314c949877d74f08c3133a9695883 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 22 Dec 2015 20:39:09 -0800 Subject: [PATCH 5/9] fix crashing when get documentHighlighting --- src/services/services.ts | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 0ffd1138cba..2bda7bf0e72 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5983,14 +5983,37 @@ namespace ts { // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, undefined); } }); return result; } - function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[]): void { + /** + * Find symbol of the given property-name and add the symbol to the given result array + * @param symbol a symbol to start searching for the given propertyName + * @param propertyName a name of property to serach for + * @param result an array of symbol of found property symbols + * @param previousIterationSymbol a symbol from previous iteration of calling this function to prevent infinite revisitng of the same symbol. + * The value of previousIterationSymbol is undefined when the function is first called. + */ + function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], previousIterationSymbol: Symbol): void { + // If the current symbol is the smae as the previous-iteration symbol, we can just return as the symbol has already been visited + // This is particularly important for the following cases, so that we do not inifinitely visit the same symbol. + // For example: + // interface C extends C { + // /*findRef*/propName: string; + // } + // The first time getPropertySymbolsFromBaseTypes is called when finding-all-references at propName, + // the symbol argument will be the symbol of an interface "C" and previousIterationSymbol is undefined, + // the function will add any found symbol of the property-name, then its sub-routine will call + // getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already + // visited symbol, interface "C", the sub- routine will pass the current symbol as previousIterationSymbol. + if (symbol === previousIterationSymbol) { + return; + } + if (symbol && symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { forEach(symbol.getDeclarations(), declaration => { if (declaration.kind === SyntaxKind.ClassDeclaration) { @@ -6014,7 +6037,7 @@ namespace ts { } // Visit the typeReference as well to see if it directly or indirectly use that property - getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result); + getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, symbol); } } } @@ -6055,7 +6078,7 @@ namespace ts { // see if any is in the list if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { const result: Symbol[] = []; - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, undefined); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); } From 6dfe29ec31e6004dbdaf17fa24e6f4ef9536e4ac Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 8 Jan 2016 03:34:43 -0800 Subject: [PATCH 6/9] Add tests --- ...documentHighlightAtInheritedProperties5.ts | 30 +++++++++++++++++++ ...documentHighlightAtInheritedProperties6.ts | 30 +++++++++++++++++++ .../findAllRefsInheritedProperties4.ts | 30 +++++++++++++++++++ .../findAllRefsInheritedProperties5.ts | 30 +++++++++++++++++++ .../referencesForInheritedProperties8.ts | 27 +++++++++++++++++ .../referencesForInheritedProperties9.ts | 21 +++++++++++++ .../fourslash/renameInheritedProperties1.ts | 4 +-- .../fourslash/renameInheritedProperties5.ts | 17 +++++++++++ .../fourslash/renameInheritedProperties6.ts | 17 +++++++++++ .../fourslash/renameInheritedProperties7.ts | 19 ++++++++++++ .../fourslash/renameInheritedProperties8.ts | 19 ++++++++++++ 11 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts create mode 100644 tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts create mode 100644 tests/cases/fourslash/findAllRefsInheritedProperties4.ts create mode 100644 tests/cases/fourslash/findAllRefsInheritedProperties5.ts create mode 100644 tests/cases/fourslash/referencesForInheritedProperties8.ts create mode 100644 tests/cases/fourslash/referencesForInheritedProperties9.ts create mode 100644 tests/cases/fourslash/renameInheritedProperties5.ts create mode 100644 tests/cases/fourslash/renameInheritedProperties6.ts create mode 100644 tests/cases/fourslash/renameInheritedProperties7.ts create mode 100644 tests/cases/fourslash/renameInheritedProperties8.ts diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts new file mode 100644 index 00000000000..b5f4cbb00a7 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts @@ -0,0 +1,30 @@ +/// + +// @Filename: file1.ts +//// interface C extends D { +//// /*0*/prop0: string; +//// /*1*/prop1: number; +//// } +//// +//// interface D extends C { +//// /*2*/prop0: string; +//// /*3*/prop1: number; +//// } +//// +//// var d: D; +//// d./*4*/prop1; + +goTo.marker("0"); +verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); + +goTo.marker("1"); +verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); + +goTo.marker("2"); +verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); + +goTo.marker("3"); +verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); + +goTo.marker("4"); +verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); \ No newline at end of file diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts new file mode 100644 index 00000000000..8f1089e567d --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts @@ -0,0 +1,30 @@ +/// + +// @Filename: file1.ts +//// class C extends D { +//// /*0*/prop0: string; +//// /*1*/prop1: string; +//// } +//// +//// class D extends C { +//// /*2*/prop0: string; +//// /*3*/prop1: string; +//// } +//// +//// var d: D; +//// d./*4*/prop1; + +goTo.marker("0"); +verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); + +goTo.marker("1"); +verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); + +goTo.marker("2"); +verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); + +goTo.marker("3"); +verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); + +goTo.marker("4"); +verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties4.ts b/tests/cases/fourslash/findAllRefsInheritedProperties4.ts new file mode 100644 index 00000000000..bcd41331f73 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties4.ts @@ -0,0 +1,30 @@ +/// + +//// interface C extends D { +//// [|prop0|]: string; // r0 +//// [|prop1|]: number; // r1 +//// } +//// +//// interface D extends C { +//// [|prop0|]: string; // r2 +//// } +//// +//// var d: D; +//// d.[|prop0|]; // r3 +//// d.[|prop1|]; // r4 + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3, r4] = ranges; +verifyReferences(r0, [r0, r2, r3]); +verifyReferences(r1, [r1]); +verifyReferences(r2, [r0, r2, r3]); +verifyReferences(r3, [r0, r2, r3]); +verifyReferences(r4, []); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties5.ts b/tests/cases/fourslash/findAllRefsInheritedProperties5.ts new file mode 100644 index 00000000000..d4e02a36b09 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInheritedProperties5.ts @@ -0,0 +1,30 @@ +/// + +//// class C extends D { +//// [|prop0|]: string; // r0 +//// [|prop1|]: number; // r1 +//// } +//// +//// class D extends C { +//// [|prop0|]: string; // r2 +//// } +//// +//// var d: D; +//// d.[|prop0|]; // r3 +//// d.[|prop1|]; // r4 + +function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { + goTo.position(query.start); + for (const ref of references) { + verify.referencesAtPositionContains(ref); + } +} + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +const [r0, r1, r2, r3, r4] = ranges; +verifyReferences(r0, [r0]); +verifyReferences(r1, [r1]); +verifyReferences(r2, [r2, r3]); +verifyReferences(r3, [r2, r3]); +verifyReferences(r4, []); diff --git a/tests/cases/fourslash/referencesForInheritedProperties8.ts b/tests/cases/fourslash/referencesForInheritedProperties8.ts new file mode 100644 index 00000000000..f34b327a472 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties8.ts @@ -0,0 +1,27 @@ +/// + +//// interface C extends D { +//// /*0*/propD: number; +//// } +//// interface D extends C { +//// /*1*/propD: string; +//// /*3*/propC: number; +//// } +//// var d: D; +//// d./*2*/propD; +//// d./*4*/propC; + +goTo.marker("0"); +verify.referencesCountIs(3); + +goTo.marker("1"); +verify.referencesCountIs(3); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(2); + +goTo.marker("4"); +verify.referencesCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties9.ts b/tests/cases/fourslash/referencesForInheritedProperties9.ts new file mode 100644 index 00000000000..b348d6e8cf6 --- /dev/null +++ b/tests/cases/fourslash/referencesForInheritedProperties9.ts @@ -0,0 +1,21 @@ +/// + +//// class D extends C { +//// /*0*/prop1: string; +//// } +//// +//// class C extends D { +//// /*1*/prop1: string; +//// } +//// +//// var c: C; +//// c./*2*/prop1; + +goTo.marker("0"); +verify.referencesCountIs(1); + +goTo.marker("1"); +verify.referencesCountIs(2) + +goTo.marker("2"); +verify.referencesCountIs(2) \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties1.ts b/tests/cases/fourslash/renameInheritedProperties1.ts index f0b2acf3b14..4698fe3d97b 100644 --- a/tests/cases/fourslash/renameInheritedProperties1.ts +++ b/tests/cases/fourslash/renameInheritedProperties1.ts @@ -7,9 +7,9 @@ //// var v: class1; //// v.[|propName|]; -let ranges = test.ranges(); +const ranges = test.ranges(); verify.assertHasRanges(ranges); -for (let range of ranges) { +for (const range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); } \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties5.ts b/tests/cases/fourslash/renameInheritedProperties5.ts new file mode 100644 index 00000000000..45058827747 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties5.ts @@ -0,0 +1,17 @@ +/// + +//// interface C extends D { +//// propC: number; +//// } +//// interface D extends C { +//// [|propD|]: string; +//// } +//// var d: D; +//// d.[|propD|]; + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (const range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} diff --git a/tests/cases/fourslash/renameInheritedProperties6.ts b/tests/cases/fourslash/renameInheritedProperties6.ts new file mode 100644 index 00000000000..6bdd32ce3e0 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties6.ts @@ -0,0 +1,17 @@ +/// + +//// interface C extends D { +//// propD: number; +//// } +//// interface D extends C { +//// [|propC|]: number; +//// } +//// var d: D; +//// d.[|propC|]; + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (const range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties7.ts b/tests/cases/fourslash/renameInheritedProperties7.ts new file mode 100644 index 00000000000..a2f8c5a2b51 --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties7.ts @@ -0,0 +1,19 @@ +/// + +//// class C extends D { +//// [|prop1|]: string; +//// } +//// +//// class D extends C { +//// prop1: string; +//// } +//// +//// var c: C; +//// c.[|prop1|]; + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (const range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameInheritedProperties8.ts b/tests/cases/fourslash/renameInheritedProperties8.ts new file mode 100644 index 00000000000..119e1a477aa --- /dev/null +++ b/tests/cases/fourslash/renameInheritedProperties8.ts @@ -0,0 +1,19 @@ +/// + +//// class C implements D { +//// [|prop1|]: string; +//// } +//// +//// interface D extends C { +//// [|prop1|]: string; +//// } +//// +//// var c: C; +//// c.[|prop1|]; + +const ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (const range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file From 68f6d0c1ad840499cf64f2d087a968063551138d Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 8 Jan 2016 03:34:57 -0800 Subject: [PATCH 7/9] Address PR feedback --- src/services/services.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 2bda7bf0e72..ce41db2205f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5983,7 +5983,7 @@ namespace ts { // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, undefined); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, {}); } }); @@ -5995,10 +5995,11 @@ namespace ts { * @param symbol a symbol to start searching for the given propertyName * @param propertyName a name of property to serach for * @param result an array of symbol of found property symbols - * @param previousIterationSymbol a symbol from previous iteration of calling this function to prevent infinite revisitng of the same symbol. + * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisitng of the same symbol. * The value of previousIterationSymbol is undefined when the function is first called. */ - function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], previousIterationSymbol: Symbol): void { + function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], + previousIterationSymbolsCache: SymbolTable): void { // If the current symbol is the smae as the previous-iteration symbol, we can just return as the symbol has already been visited // This is particularly important for the following cases, so that we do not inifinitely visit the same symbol. // For example: @@ -6010,7 +6011,7 @@ namespace ts { // the function will add any found symbol of the property-name, then its sub-routine will call // getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already // visited symbol, interface "C", the sub- routine will pass the current symbol as previousIterationSymbol. - if (symbol === previousIterationSymbol) { + if (previousIterationSymbolsCache && previousIterationSymbolsCache[symbol.name] === symbol) { return; } @@ -6037,7 +6038,8 @@ namespace ts { } // Visit the typeReference as well to see if it directly or indirectly use that property - getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, symbol); + previousIterationSymbolsCache[symbol.name] = symbol; + getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache); } } } @@ -6078,7 +6080,7 @@ namespace ts { // see if any is in the list if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { const result: Symbol[] = []; - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, undefined); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, {}); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); } From 3391abf51ac009ab6c4572a2ea31f781fbc9e623 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 13 Jan 2016 15:10:29 -0800 Subject: [PATCH 8/9] Address PR --- src/services/services.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index ce41db2205f..9c131f8f044 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5983,7 +5983,7 @@ namespace ts { // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, {}); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ {}); } }); @@ -6000,8 +6000,8 @@ namespace ts { */ function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], previousIterationSymbolsCache: SymbolTable): void { - // If the current symbol is the smae as the previous-iteration symbol, we can just return as the symbol has already been visited - // This is particularly important for the following cases, so that we do not inifinitely visit the same symbol. + // If the current symbol is the same as the previous-iteration symbol, we can just return the symbol that has already been visited + // This is particularly important for the following cases, so that we do not infinitely visit the same symbol. // For example: // interface C extends C { // /*findRef*/propName: string; @@ -6080,7 +6080,7 @@ namespace ts { // see if any is in the list if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { const result: Symbol[] = []; - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, {}); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ {}); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); } From d4a04a11d2931341baac7a76d61de63b08f606a4 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 13 Jan 2016 16:48:48 -0800 Subject: [PATCH 9/9] Address PR --- src/services/services.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 9c131f8f044..dcc01300e96 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6010,8 +6010,8 @@ namespace ts { // the symbol argument will be the symbol of an interface "C" and previousIterationSymbol is undefined, // the function will add any found symbol of the property-name, then its sub-routine will call // getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already - // visited symbol, interface "C", the sub- routine will pass the current symbol as previousIterationSymbol. - if (previousIterationSymbolsCache && previousIterationSymbolsCache[symbol.name] === symbol) { + // visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol. + if (hasProperty(previousIterationSymbolsCache, symbol.name)) { return; }