Fix getReferences for labels

This commit is contained in:
Mohamed Hegazy 2014-08-20 15:35:30 -07:00
parent 55512faa0d
commit 978c2ef670
4 changed files with 57 additions and 12 deletions

View file

@ -2148,20 +2148,16 @@ module ts {
// Labels
if (isLabelName(node)) {
var labelName = (<Identifier>node).text;
var labelScope: Node;
if (isJumpStatementTarget(node)) {
var labelDefinition = getTargetLabel((<BreakOrContinueStatement>node.parent), (<Identifier>node).text);
labelScope = labelDefinition ? labelDefinition.parent : getContainerNode(node);
// if we have a label definition, look within its statement for references, if not, then
// the label is undefined, just return a set of one for the current node.
return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : [getReferenceEntry(node)];
}
else {
// it is a label definition and not a target, the scope is the labeledStatement
labelScope = node.parent;
// it is a label definition and not a target, search within the parent labeledStatement
return getLabelReferencesInNode(node.parent, <Identifier>node);
}
return getLabelReferencesInNode(labelScope, labelName);
}
var symbol = typeInfoResolver.getSymbolInfo(node);
@ -2246,16 +2242,23 @@ module ts {
return positions;
}
function getLabelReferencesInNode(container: Node, labelName: string): ReferenceEntry[] {
function getLabelReferencesInNode(container: Node, targetLabel: Identifier): ReferenceEntry[] {
var result: ReferenceEntry[] = [];
var sourceFile = container.getSourceFile();
var labelName = targetLabel.text;
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) {
if (!node || node.getWidth() !== labelName.length) {
return;
}
// Only pick labels that are either the target label, or have a target that is the target label
if (node === targetLabel ||
(isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel)) {
result.push(getReferenceEntry(node));
}
});

View file

@ -9,4 +9,4 @@
////}
goTo.marker("1");
verify.referencesCountIs(2);
verify.referencesCountIs(1);

View file

@ -0,0 +1,28 @@
/// <reference path='fourslash.ts'/>
// References to shadowed label
/////*outer1*/label: while (true) {
//// if (false) break /*outer2*/label;
//// function blah() {
/////*inner1*/label: while (true) {
//// if (false) break /*inner2*/label;
//// }
//// }
//// if (false) break /*outer3*/label;
//// }
goTo.marker("outer1");
verify.referencesCountIs(3);
goTo.marker("outer2");
verify.referencesCountIs(3);
goTo.marker("outer3");
verify.referencesCountIs(3);
goTo.marker("inner1");
verify.referencesCountIs(2);
goTo.marker("inner2");
verify.referencesCountIs(2);

View file

@ -0,0 +1,14 @@
/// <reference path='fourslash.ts'/>
// References to lable wiht close names
/////*1*/labela: while (true) {
/////*2*/labelb: while (false) { break labelb; }
//// break labelc;
////}
goTo.marker("1");
verify.referencesCountIs(1);
goTo.marker("2");
verify.referencesCountIs(2);