Skip to content

Commit

Permalink
Improve null handling
Browse files Browse the repository at this point in the history
  • Loading branch information
amcasey committed Jun 16, 2022
1 parent a12e29e commit 0388f07
Showing 1 changed file with 27 additions and 22 deletions.
49 changes: 27 additions & 22 deletions src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ namespace ts.server {
let progress = false;
perProjectResults.forEach((referencedSymbols, project) => {
if (updatedProjects.has(project)) return;
if (!referencedSymbols) return;
const updated = project.getLanguageService().updateIsDefinitionOfReferencedSymbols(referencedSymbols, knownSymbolSpans);
if (updated) {
updatedProjects.add(project);
Expand All @@ -423,6 +424,7 @@ namespace ts.server {

perProjectResults.forEach((referencedSymbols, project) => {
if (updatedProjects.has(project)) return;
if (!referencedSymbols) return;
for (const referencedSymbol of referencedSymbols) {
for (const ref of referencedSymbol.references) {
ref.isDefinition = false;
Expand All @@ -441,27 +443,29 @@ namespace ts.server {
// Otherwise, it just ends up attached to the first corresponding def we happen to process. The others may or may not be
// dropped later when we check for defs with ref-count 0.
perProjectResults.forEach((projectResults, project) => {
for (const referencedSymbol of projectResults) {
const mappedDefinitionFile = getMappedLocationForProject(documentSpanLocation(referencedSymbol.definition), project);
const definition: ReferencedSymbolDefinitionInfo = mappedDefinitionFile === undefined ?
referencedSymbol.definition :
{
...referencedSymbol.definition,
textSpan: createTextSpan(mappedDefinitionFile.pos, referencedSymbol.definition.textSpan.length), // Why would the length be the same in the original?
fileName: mappedDefinitionFile.fileName,
contextSpan: getMappedContextSpanForProject(referencedSymbol.definition, project)
};
if (projectResults) {
for (const referencedSymbol of projectResults) {
const mappedDefinitionFile = getMappedLocationForProject(documentSpanLocation(referencedSymbol.definition), project);
const definition: ReferencedSymbolDefinitionInfo = mappedDefinitionFile === undefined ?
referencedSymbol.definition :
{
...referencedSymbol.definition,
textSpan: createTextSpan(mappedDefinitionFile.pos, referencedSymbol.definition.textSpan.length), // Why would the length be the same in the original?
fileName: mappedDefinitionFile.fileName,
contextSpan: getMappedContextSpanForProject(referencedSymbol.definition, project)
};

let symbolToAddTo = find(results, o => documentSpansEqual(o.definition, definition));
if (!symbolToAddTo) {
symbolToAddTo = { definition, references: [] };
results.push(symbolToAddTo);
}
let symbolToAddTo = find(results, o => documentSpansEqual(o.definition, definition));
if (!symbolToAddTo) {
symbolToAddTo = { definition, references: [] };
results.push(symbolToAddTo);
}

for (const ref of referencedSymbol.references) {
if (!seenRefs.has(ref) && !getMappedLocationForProject(documentSpanLocation(ref), project)) {
seenRefs.add(ref);
symbolToAddTo.references.push(ref);
for (const ref of referencedSymbol.references) {
if (!seenRefs.has(ref) && !getMappedLocationForProject(documentSpanLocation(ref), project)) {
seenRefs.add(ref);
symbolToAddTo.references.push(ref);
}
}
}
}
Expand Down Expand Up @@ -504,9 +508,9 @@ namespace ts.server {
isForRename: boolean,
getResultsForPosition: (project: Project, location: DocumentPosition) => readonly TResult[] | undefined,
forPositionInResult: (result: TResult, cb: (location: DocumentPosition) => void) => void,
): readonly TResult[] | ESMap<Project, readonly TResult[]> {
): readonly TResult[] | ESMap<Project, undefined | readonly TResult[]> {
// If `getResultsForPosition` returns results for a project, they go in here
const resultsMap = new Map<Project, readonly TResult[]>();
const resultsMap = new Map<Project, undefined | readonly TResult[]>();

const queue: ProjectAndLocation[] = [];

Expand Down Expand Up @@ -588,7 +592,8 @@ namespace ts.server {
// it easier for the caller to skip post-processing.
if (resultsMap.size === 1) {
const it = resultsMap.values().next();
return it.done ? emptyArray : it.value; // There may not be any results at all
Debug.assert(!it.done);
return it.value ?? emptyArray;
}

return resultsMap;
Expand Down

0 comments on commit 0388f07

Please sign in to comment.