From bfd13347d4a69ab0082d4e49359b905e635d4630 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 13 Aug 2014 13:01:32 -0700 Subject: [PATCH] Handel getRefrences for labels --- src/services/services.ts | 37 +++++++++++++++++--- tests/cases/fourslash/referencesForLabel.ts | 23 ++++++++++++ tests/cases/fourslash/referencesForLabel2.ts | 12 +++++++ tests/cases/fourslash/referencesForLabel3.ts | 10 ++++++ tests/cases/fourslash/referencesForLabel4.ts | 15 ++++++++ 5 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/referencesForLabel.ts create mode 100644 tests/cases/fourslash/referencesForLabel2.ts create mode 100644 tests/cases/fourslash/referencesForLabel3.ts create mode 100644 tests/cases/fourslash/referencesForLabel4.ts diff --git a/src/services/services.ts b/src/services/services.ts index d9ed4add89..143594e75c 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1264,7 +1264,7 @@ module ts { (node.parent).label === node; } - function isLabel(node: Node): boolean { + function isLabelName(node: Node): boolean { return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node); } @@ -1881,6 +1881,7 @@ module ts { return node; } switch (node.kind) { + case SyntaxKind.SourceFile: case SyntaxKind.Method: case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: @@ -2105,12 +2106,21 @@ module ts { } // Labels - if (isLabel(node)) { + if (isLabelName(node)) { var labelName = (node).text; - var labelDefinition = isJumpStatementTarget(node) ? getTargetLabel((node.parent), (node).text) : node; - /// TODO handel labels - return undefined; + var labelScope: Node; + + if (isJumpStatementTarget(node)) { + var labelDefinition = getTargetLabel((node.parent), (node).text); + labelScope = labelDefinition ? labelDefinition.parent : getContainerNode(node); + } + else { + // it is a label definition and not a target, the scope is the labeledStatement + labelScope = node.parent; + } + + return getLabelReferencesInNode(labelScope, labelName); } var symbol = typeChecker.getSymbolInfo(node); @@ -2192,6 +2202,23 @@ module ts { return positions; } + function getLabelReferencesInNode(container: Node, labelName: string): ReferenceEntry[] { + var result: ReferenceEntry[] = []; + var sourceFile = container.getSourceFile(); + var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); + if (possiblePositions && possiblePositions.length > 0) { + possiblePositions.forEach(position => { + cancellationToken.throwIfCancellationRequested(); + + var node = getNodeAtPosition(sourceFile, position); + if (node && isLabelName(node) && node.getWidth() === labelName.length) { + result.push(getReferenceEntry(node)); + } + }); + } + return result; + } + function getReferencesInNode(container: Node, searchSymbol: Symbol, result: ReferenceEntry[]): void { var searchSymbolName = searchSymbol.getName(); diff --git a/tests/cases/fourslash/referencesForLabel.ts b/tests/cases/fourslash/referencesForLabel.ts new file mode 100644 index 0000000000..ee5df8049c --- /dev/null +++ b/tests/cases/fourslash/referencesForLabel.ts @@ -0,0 +1,23 @@ +/// + +// Valid References for a label + +/////*1*/label: while (true) { +//// if (false) break /*2*/label; +//// if (true) continue /*3*/label; +////} +//// +/////*4*/label: while (false) { } +////var label = "label"; + +goTo.marker("1"); +verify.referencesCountIs(3); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(3); + +goTo.marker("4"); +verify.referencesCountIs(1); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForLabel2.ts b/tests/cases/fourslash/referencesForLabel2.ts new file mode 100644 index 0000000000..5919f568cb --- /dev/null +++ b/tests/cases/fourslash/referencesForLabel2.ts @@ -0,0 +1,12 @@ +/// + +// References to undefined label + +////var label = "label"; +////while (true) { +//// if (false) break /*1*/label; +//// if (true) continue label; +////} + +goTo.marker("1"); +verify.referencesCountIs(2); diff --git a/tests/cases/fourslash/referencesForLabel3.ts b/tests/cases/fourslash/referencesForLabel3.ts new file mode 100644 index 0000000000..5a4c389321 --- /dev/null +++ b/tests/cases/fourslash/referencesForLabel3.ts @@ -0,0 +1,10 @@ +/// + +// References to unused label + +/////*1*/label: while (true) { +//// var label = "label"; +////} + +goTo.marker("1"); +verify.referencesCountIs(1); diff --git a/tests/cases/fourslash/referencesForLabel4.ts b/tests/cases/fourslash/referencesForLabel4.ts new file mode 100644 index 0000000000..4288046ece --- /dev/null +++ b/tests/cases/fourslash/referencesForLabel4.ts @@ -0,0 +1,15 @@ +/// + +// References to a label outside function bounderies + +/////*1*/label: function foo(label) { +//// while (true) { +//// break /*2*/label; +//// } +////} + +goTo.marker("1"); +verify.referencesCountIs(2); + +goTo.marker("2"); +verify.referencesCountIs(2);