Fix getReferences for labels
This commit is contained in:
parent
55512faa0d
commit
978c2ef670
4 changed files with 57 additions and 12 deletions
|
@ -2148,20 +2148,16 @@ module ts {
|
||||||
|
|
||||||
// Labels
|
// Labels
|
||||||
if (isLabelName(node)) {
|
if (isLabelName(node)) {
|
||||||
var labelName = (<Identifier>node).text;
|
|
||||||
|
|
||||||
var labelScope: Node;
|
|
||||||
|
|
||||||
if (isJumpStatementTarget(node)) {
|
if (isJumpStatementTarget(node)) {
|
||||||
var labelDefinition = getTargetLabel((<BreakOrContinueStatement>node.parent), (<Identifier>node).text);
|
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 {
|
else {
|
||||||
// it is a label definition and not a target, the scope is the labeledStatement
|
// it is a label definition and not a target, search within the parent labeledStatement
|
||||||
labelScope = node.parent;
|
return getLabelReferencesInNode(node.parent, <Identifier>node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getLabelReferencesInNode(labelScope, labelName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var symbol = typeInfoResolver.getSymbolInfo(node);
|
var symbol = typeInfoResolver.getSymbolInfo(node);
|
||||||
|
@ -2246,16 +2242,23 @@ module ts {
|
||||||
return positions;
|
return positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLabelReferencesInNode(container: Node, labelName: string): ReferenceEntry[] {
|
function getLabelReferencesInNode(container: Node, targetLabel: Identifier): ReferenceEntry[] {
|
||||||
var result: ReferenceEntry[] = [];
|
var result: ReferenceEntry[] = [];
|
||||||
var sourceFile = container.getSourceFile();
|
var sourceFile = container.getSourceFile();
|
||||||
|
var labelName = targetLabel.text;
|
||||||
var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd());
|
var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd());
|
||||||
if (possiblePositions && possiblePositions.length > 0) {
|
if (possiblePositions && possiblePositions.length > 0) {
|
||||||
possiblePositions.forEach(position => {
|
possiblePositions.forEach(position => {
|
||||||
cancellationToken.throwIfCancellationRequested();
|
cancellationToken.throwIfCancellationRequested();
|
||||||
|
|
||||||
var node = getNodeAtPosition(sourceFile, position);
|
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));
|
result.push(getReferenceEntry(node));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,4 +9,4 @@
|
||||||
////}
|
////}
|
||||||
|
|
||||||
goTo.marker("1");
|
goTo.marker("1");
|
||||||
verify.referencesCountIs(2);
|
verify.referencesCountIs(1);
|
||||||
|
|
28
tests/cases/fourslash/referencesForLabel5.ts
Normal file
28
tests/cases/fourslash/referencesForLabel5.ts
Normal 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);
|
14
tests/cases/fourslash/referencesForLabel6.ts
Normal file
14
tests/cases/fourslash/referencesForLabel6.ts
Normal 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);
|
Loading…
Reference in a new issue