Skip to content

Commit 9fc864c

Browse files
committed
Handle case sensitivity when comparing the file names of document span
Fixes #53041
1 parent 35e71e4 commit 9fc864c

File tree

4 files changed

+28
-34
lines changed

4 files changed

+28
-34
lines changed

src/harness/fourslashImpl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1569,7 +1569,7 @@ export class TestState {
15691569
details.push({ location: contextSpanEnd, locationMarker: "|>", span, type: "contextEnd" });
15701570
}
15711571

1572-
if (additionalSpan && ts.documentSpansEqual(additionalSpan, span)) {
1572+
if (additionalSpan && ts.documentSpansEqual(additionalSpan, span, this.languageServiceAdapterHost.useCaseSensitiveFileNames())) {
15731573
// This span is same as text span
15741574
groupedSpanForAdditionalSpan = span;
15751575
}

src/server/session.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import {
5353
formatting,
5454
getDeclarationFromName,
5555
getDeclarationOfKind,
56+
getDocumentSpansEqualityComparer,
5657
getEmitDeclarations,
5758
getEntrypointsFromPackageJsonInfo,
5859
getLineAndCharacterOfPosition,
@@ -498,8 +499,8 @@ interface ProjectNavigateToItems {
498499
navigateToItems: readonly NavigateToItem[];
499500
}
500501

501-
function createDocumentSpanSet(): Set<DocumentSpan> {
502-
return createSet(({ textSpan }) => textSpan.start + 100003 * textSpan.length, documentSpansEqual);
502+
function createDocumentSpanSet(useCaseSensitiveFileNames: boolean): Set<DocumentSpan> {
503+
return createSet(({ textSpan }) => textSpan.start + 100003 * textSpan.length, getDocumentSpansEqualityComparer(useCaseSensitiveFileNames));
503504
}
504505

505506
function getRenameLocationsWorker(
@@ -509,6 +510,7 @@ function getRenameLocationsWorker(
509510
findInStrings: boolean,
510511
findInComments: boolean,
511512
preferences: protocol.UserPreferences,
513+
useCaseSensitiveFileNames: boolean,
512514
): readonly RenameLocation[] {
513515
const perProjectResults = getPerProjectReferences(
514516
projects,
@@ -525,7 +527,7 @@ function getRenameLocationsWorker(
525527
}
526528

527529
const results: RenameLocation[] = [];
528-
const seen = createDocumentSpanSet();
530+
const seen = createDocumentSpanSet(useCaseSensitiveFileNames);
529531

530532
perProjectResults.forEach((projectResults, project) => {
531533
for (const result of projectResults) {
@@ -552,6 +554,7 @@ function getReferencesWorker(
552554
projects: Projects,
553555
defaultProject: Project,
554556
initialLocation: DocumentPosition,
557+
useCaseSensitiveFileNames: boolean,
555558
logger: Logger,
556559
): readonly ReferencedSymbol[] {
557560
const perProjectResults = getPerProjectReferences(
@@ -593,7 +596,7 @@ function getReferencesWorker(
593596
}
594597
else {
595598
// Correct isDefinition properties from projects other than defaultProject
596-
const knownSymbolSpans = createDocumentSpanSet();
599+
const knownSymbolSpans = createDocumentSpanSet(useCaseSensitiveFileNames);
597600
for (const referencedSymbol of defaultProjectResults) {
598601
for (const ref of referencedSymbol.references) {
599602
if (ref.isDefinition) {
@@ -632,7 +635,7 @@ function getReferencesWorker(
632635
// of each definition and merging references from all the projects where they appear.
633636

634637
const results: ReferencedSymbol[] = [];
635-
const seenRefs = createDocumentSpanSet(); // It doesn't make sense to have a reference in two definition lists, so we de-dup globally
638+
const seenRefs = createDocumentSpanSet(useCaseSensitiveFileNames); // It doesn't make sense to have a reference in two definition lists, so we de-dup globally
636639

637640
// TODO: We might end up with a more logical allocation of refs to defs if we pre-sorted the defs by descending ref-count.
638641
// Otherwise, it just ends up attached to the first corresponding def we happen to process. The others may or may not be
@@ -649,7 +652,7 @@ function getReferencesWorker(
649652
contextSpan: getMappedContextSpanForProject(referencedSymbol.definition, project),
650653
};
651654

652-
let symbolToAddTo = find(results, o => documentSpansEqual(o.definition, definition));
655+
let symbolToAddTo = find(results, o => documentSpansEqual(o.definition, definition, useCaseSensitiveFileNames));
653656
if (!symbolToAddTo) {
654657
symbolToAddTo = { definition, references: [] };
655658
results.push(symbolToAddTo);
@@ -1542,7 +1545,10 @@ export class Session<TMessage = string> implements EventSender {
15421545
);
15431546

15441547
if (needsJsResolution) {
1545-
const definitionSet = createSet<DefinitionInfo>(d => d.textSpan.start, documentSpansEqual);
1548+
const definitionSet = createSet<DefinitionInfo>(
1549+
d => d.textSpan.start,
1550+
getDocumentSpansEqualityComparer(this.host.useCaseSensitiveFileNames),
1551+
);
15461552
definitions?.forEach(d => definitionSet.add(d));
15471553
const noDtsProject = project.getNoDtsResolutionProject(file);
15481554
const ls = noDtsProject.getLanguageService();
@@ -1993,6 +1999,7 @@ export class Session<TMessage = string> implements EventSender {
19931999
!!args.findInStrings,
19942000
!!args.findInComments,
19952001
preferences,
2002+
this.host.useCaseSensitiveFileNames,
19962003
);
19972004
if (!simplifiedResult) return locations;
19982005
return { info: renameInfo, locs: this.toSpanGroups(locations) };
@@ -2029,6 +2036,7 @@ export class Session<TMessage = string> implements EventSender {
20292036
projects,
20302037
this.getDefaultProject(args),
20312038
{ fileName: args.file, pos: position },
2039+
this.host.useCaseSensitiveFileNames,
20322040
this.logger,
20332041
);
20342042

@@ -2054,7 +2062,7 @@ export class Session<TMessage = string> implements EventSender {
20542062
const preferences = this.getPreferences(toNormalizedPath(fileName));
20552063

20562064
const references: ReferenceEntry[] = [];
2057-
const seen = createDocumentSpanSet();
2065+
const seen = createDocumentSpanSet(this.host.useCaseSensitiveFileNames);
20582066

20592067
forEachProjectInProjects(projects, /*path*/ undefined, project => {
20602068
if (project.getCancellationToken().isCancellationRequested()) return;

src/services/utilities.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ import {
5959
EndOfFileToken,
6060
endsWith,
6161
ensureScriptKind,
62+
EqualityComparer,
6263
EqualityOperator,
64+
equateStringsCaseInsensitive,
65+
equateStringsCaseSensitive,
6366
escapeString,
6467
ExportAssignment,
6568
ExportDeclaration,
@@ -2663,8 +2666,14 @@ export function textSpansEqual(a: TextSpan | undefined, b: TextSpan | undefined)
26632666
return !!a && !!b && a.start === b.start && a.length === b.length;
26642667
}
26652668
/** @internal */
2666-
export function documentSpansEqual(a: DocumentSpan, b: DocumentSpan): boolean {
2667-
return a.fileName === b.fileName && textSpansEqual(a.textSpan, b.textSpan);
2669+
export function documentSpansEqual(a: DocumentSpan, b: DocumentSpan, useCaseSensitiveFileNames: boolean): boolean {
2670+
return (useCaseSensitiveFileNames ? equateStringsCaseSensitive : equateStringsCaseInsensitive)(a.fileName, b.fileName) &&
2671+
textSpansEqual(a.textSpan, b.textSpan);
2672+
}
2673+
2674+
/** @internal */
2675+
export function getDocumentSpansEqualityComparer(useCaseSensitiveFileNames: boolean): EqualityComparer<DocumentSpan> {
2676+
return (a, b) => documentSpansEqual(a, b, useCaseSensitiveFileNames);
26682677
}
26692678

26702679
/**

tests/baselines/reference/tsserver/rename/with-symlinks-and-case-difference.js

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -500,29 +500,6 @@ Info seq [hh:mm:ss:mss] response:
500500
}
501501
]
502502
},
503-
{
504-
"file": "C:/temp/test/project1/index.ts",
505-
"locs": [
506-
{
507-
"start": {
508-
"line": 1,
509-
"offset": 17
510-
},
511-
"end": {
512-
"line": 1,
513-
"offset": 23
514-
},
515-
"contextStart": {
516-
"line": 1,
517-
"offset": 1
518-
},
519-
"contextEnd": {
520-
"line": 2,
521-
"offset": 2
522-
}
523-
}
524-
]
525-
},
526503
{
527504
"file": "c:/temp/test/project2/index.ts",
528505
"locs": [

0 commit comments

Comments
 (0)