From fefe2fb0931bd3a85cd2d2d6d68cd85a0a3e8114 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 22 Aug 2014 16:30:21 -0700 Subject: [PATCH] Implement getScope --- src/services/services.ts | 41 +++++++++++-- tests/cases/fourslash/referencesForGlobals.ts | 60 +++++++++---------- .../cases/fourslash/referencesForGlobals2.ts | 17 ++++++ .../cases/fourslash/referencesForGlobals3.ts | 17 ++++++ .../cases/fourslash/referencesForGlobals4.ts | 17 ++++++ .../cases/fourslash/referencesForGlobals5.ts | 19 ++++++ 6 files changed, 137 insertions(+), 34 deletions(-) create mode 100644 tests/cases/fourslash/referencesForGlobals2.ts create mode 100644 tests/cases/fourslash/referencesForGlobals3.ts create mode 100644 tests/cases/fourslash/referencesForGlobals4.ts create mode 100644 tests/cases/fourslash/referencesForGlobals5.ts diff --git a/src/services/services.ts b/src/services/services.ts index b37602bd9d..a1922231b0 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2163,7 +2163,7 @@ module ts { // Compute the meaning from the location and the symbol it references var searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), symbol.getDeclarations()); - var scope = getSymbolScope(symbol, node); + var scope = getSymbolScope(symbol); if (scope) { result = []; @@ -2184,9 +2184,42 @@ module ts { return result; - function getSymbolScope(symbol: Symbol, node: Node): Node { - /// TODO: find the enclosing scope - return undefined; + function getSymbolScope(symbol: Symbol): Node { + // If this is private property or method, the scope is the containing class + if (symbol.getFlags() && (SymbolFlags.Property | SymbolFlags.Method)) { + var privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); + if (privateDeclaration) { + return privateDeclaration.parent; + } + } + + // if this symbol is visible from its parent container, e.g. exported, then bail out + if (symbol.parent) { + return undefined; + } + + var scope: Node = undefined; + + var declarations = symbol.getDeclarations(); + for (var i = 0, n = declarations.length; i < n; i++) { + var container = getContainerNode(declarations[i]); + + if (scope && scope !== container) { + // Diffrent declarations have diffrent containers, bail out + return undefined; + } + + if (container.kind === SyntaxKind.SourceFile && !isExternalModule(container)) { + // This is a global variable and not an external module, any declaration defined + // withen this scope is visible outside the file + return undefined; + } + + // The search scope is the container node + scope = container; + } + + return scope; } function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, start: number, end: number): number[] { diff --git a/tests/cases/fourslash/referencesForGlobals.ts b/tests/cases/fourslash/referencesForGlobals.ts index 25fd9ca91e..a4efddae3d 100644 --- a/tests/cases/fourslash/referencesForGlobals.ts +++ b/tests/cases/fourslash/referencesForGlobals.ts @@ -1,32 +1,32 @@ -/// - -// Global variable reference. - -// @Filename: referencesForGlobals_1.ts -////var /*1*/global = 2; -//// -////class foo { -//// constructor (public global) { } -//// public f(global) { } -//// public f2(global) { } -////} -//// -////class bar { -//// constructor () { -//// var n = global; -//// -//// var f = new foo(''); -//// f.global = ''; -//// } -////} -//// -////var k = global; - -// @Filename: referencesForGlobals_2.ts -////var m = global; - +/// + +// Global variable reference. + +// @Filename: referencesForGlobals_1.ts +////var /*1*/global = 2; +//// +////class foo { +//// constructor (public global) { } +//// public f(global) { } +//// public f2(global) { } +////} +//// +////class bar { +//// constructor () { +//// var n = global; +//// +//// var f = new foo(''); +//// f.global = ''; +//// } +////} +//// +////var k = global; + +// @Filename: referencesForGlobals_2.ts +////var m = global; + // this line triggers a semantic/syntactic error check, remove line when 788570 is fixed -edit.insert(''); - -goTo.marker("1"); +edit.insert(''); + +goTo.marker("1"); verify.referencesCountIs(4); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForGlobals2.ts b/tests/cases/fourslash/referencesForGlobals2.ts new file mode 100644 index 0000000000..a0a35d8a08 --- /dev/null +++ b/tests/cases/fourslash/referencesForGlobals2.ts @@ -0,0 +1,17 @@ +/// + +// Global class reference. + +// @Filename: referencesForGlobals_1.ts +////class /*2*/globalClass { +//// public f() { } +////} + +// @Filename: referencesForGlobals_2.ts +////var c = /*1*/globalClass(); + +goTo.marker("1"); +verify.referencesCountIs(2); + +goTo.marker("2"); +verify.referencesCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForGlobals3.ts b/tests/cases/fourslash/referencesForGlobals3.ts new file mode 100644 index 0000000000..636e14bf62 --- /dev/null +++ b/tests/cases/fourslash/referencesForGlobals3.ts @@ -0,0 +1,17 @@ +/// + +// Global interface reference. + +// @Filename: referencesForGlobals_1.ts +////interface /*2*/globalInterface { +//// f(); +////} + +// @Filename: referencesForGlobals_2.ts +////var i: /*1*/globalInterface; + +goTo.marker("1"); +verify.referencesCountIs(2); + +goTo.marker("2"); +verify.referencesCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForGlobals4.ts b/tests/cases/fourslash/referencesForGlobals4.ts new file mode 100644 index 0000000000..ee12a1754c --- /dev/null +++ b/tests/cases/fourslash/referencesForGlobals4.ts @@ -0,0 +1,17 @@ +/// + +// Global module reference. + +// @Filename: referencesForGlobals_1.ts +////module /*2*/globalModule { +//// export f() { }; +////} + +// @Filename: referencesForGlobals_2.ts +////var m = /*1*/globalModule; + +goTo.marker("1"); +verify.referencesCountIs(2); + +goTo.marker("2"); +verify.referencesCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForGlobals5.ts b/tests/cases/fourslash/referencesForGlobals5.ts new file mode 100644 index 0000000000..9c800f116b --- /dev/null +++ b/tests/cases/fourslash/referencesForGlobals5.ts @@ -0,0 +1,19 @@ +/// + +// Global module reference. + +// @Filename: referencesForGlobals_1.ts +////module globalModule { +//// export var x; +////} +//// +////import /*2*/globalAlias = globalModule; + +// @Filename: referencesForGlobals_2.ts +////var m = /*1*/globalAlias; + +goTo.marker("1"); +verify.referencesCountIs(2); + +goTo.marker("2"); +verify.referencesCountIs(2); \ No newline at end of file