Description
There seem to be some related funny issues going on. When calling getDocumentHighlights
on the position of the hello
variable declaration in the following code snippet:
// Incorrect case:
class HelloWorld {
constructor(public name: string) { }
sayHello() {
return `Hello, ${this.name}!`;
}
};
let hello = new HelloWorld("TSLint");
hello.sayHello();
only the declaration is returned and not the usage on the next line. However, in the following code snippet, both uses are returned, correctly:
// Correct case:
class HelloWorld {
constructor(public name: string) { }
sayHello() {
return `Hello, ${this.name}!`;
}
};
if (true) {
let hello = new HelloWorld("TSLint");
hello.sayHello();
}
// Correct case (var vs. let):
class HelloWorld {
constructor(public name: string) { }
sayHello() {
return `Hello, ${this.name}!`;
}
};
var hello = new HelloWorld("TSLint");
hello.sayHello();
Also strangely, Sublime will correctly show both references in all three cases.
I've been trying to figure out the root cause but haven't been able to yet. It seems that the failure occurs specifically for lexically scoped variables declared at global scope, such as let
declarations at global scope.
In case it helps, I did notice that in the getReferencesInNode
function the array of possible positions contains exactly the two actual positions in both the incorrect and correct case. However, there is a difference when finding the relatedSymbol
:
var referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation);
if (referenceSymbol) {
var referenceSymbolDeclaration = referenceSymbol.valueDeclaration;
var shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration);
var relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation);
// NOTE (added for the Github issue):
// relatedSymbol is undefined here in incorrect case, defined in the correct case
if (relatedSymbol) {
var referencedSymbol = getReferencedSymbol(relatedSymbol);
referencedSymbol.references.push(getReferenceEntryFromNode(referenceLocation));
}
else if (!(referenceSymbol.flags & 67108864 /* Transient */) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) {
var referencedSymbol = getReferencedSymbol(shorthandValueSymbol);
referencedSymbol.references.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name));
}
}
(Related to palantir/tslint#570)