Skip to content

Commit dbd7743

Browse files
committed
Test document position mapper
1 parent 91e67ff commit dbd7743

File tree

122 files changed

+2905
-306
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+2905
-306
lines changed

src/compiler/sourcemap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,7 @@ export function createDocumentPositionMapper(host: DocumentPositionMapperHost, m
711711
return {
712712
getSourcePosition,
713713
getGeneratedPosition,
714+
generatedFile,
714715
};
715716

716717
function processMapping(mapping: Mapping): MappedPosition {
@@ -821,4 +822,5 @@ export function createDocumentPositionMapper(host: DocumentPositionMapperHost, m
821822
export const identitySourceMapConsumer: DocumentPositionMapper = {
822823
getSourcePosition: identity,
823824
getGeneratedPosition: identity,
825+
generatedFile: undefined,
824826
};

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9656,6 +9656,7 @@ export interface DocumentPositionMapperHost {
96569656
export interface DocumentPositionMapper {
96579657
getSourcePosition(input: DocumentPosition): DocumentPosition;
96589658
getGeneratedPosition(input: DocumentPosition): DocumentPosition;
9659+
generatedFile: SourceFileLike | undefined;
96599660
}
96609661

96619662
/** @internal */

src/harness/projectServiceStateLogger.ts

Lines changed: 128 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import {
22
arrayFrom,
33
compareStringsCaseSensitive,
44
Debug,
5+
DocumentPositionMapper,
56
identity,
7+
identitySourceMapConsumer,
68
isString,
79
noop,
10+
SourceMapper,
811
} from "./_namespaces/ts";
912
import {
1013
AutoImportProviderProject,
@@ -30,6 +33,7 @@ interface ProjectData {
3033
isClosed: ReturnType<Project["isClosed"]>;
3134
isOrphan: ReturnType<Project["isOrphan"]>;
3235
noOpenRef: boolean;
36+
documentPositionMappers: SourceMapper["documentPositionMappers"];
3337
autoImportProviderHost: Project["autoImportProviderHost"];
3438
noDtsResolutionProject: Project["noDtsResolutionProject"];
3539
originalConfiguredProjects: Project["originalConfiguredProjects"];
@@ -66,14 +70,21 @@ export function patchServiceForStateBaseline(service: ProjectService) {
6670

6771
const projects = new Map<Project, ProjectData>();
6872
const scriptInfos = new Map<ScriptInfo, ScriptInfoData>();
73+
const documentPositionMappers = new Map<DocumentPositionMapper, number>();
74+
let nextDocumentPositionMapperId = 1;
75+
const mapperToId = new Map<DocumentPositionMapper, number>();
6976
const logger = service.logger as LoggerWithInMemoryLogs;
7077
service.baseline = title => {
71-
const projectLogs = baselineProjects();
72-
const infoLogs = baselineScriptInfos();
73-
if (projectLogs?.length || infoLogs?.length) {
78+
const currentMappers = new Set<DocumentPositionMapper>();
79+
const projectLogs = baselineProjects(currentMappers);
80+
const infoLogs = baselineScriptInfos(currentMappers);
81+
currentMappers.delete(identitySourceMapConsumer);
82+
const mapperLogs = baselineDocumentPositionMappers(currentMappers);
83+
if (projectLogs?.length || infoLogs?.length || mapperLogs?.length) {
7484
if (title) logger.log(title);
7585
sendLogsToLogger("Projects::", projectLogs);
7686
sendLogsToLogger("ScriptInfos::", infoLogs);
87+
sendLogsToLogger("DocumentPositionMappers::", mapperLogs);
7788
}
7889
};
7990

@@ -88,7 +99,7 @@ export function patchServiceForStateBaseline(service: ProjectService) {
8899
logger.log("");
89100
}
90101

91-
function baselineProjects() {
102+
function baselineProjects(currentMappers: Set<DocumentPositionMapper>) {
92103
const autoImportProviderProjects = [] as AutoImportProviderProject[];
93104
const auxiliaryProjects = [] as AuxiliaryProject[];
94105
return baselineState(
@@ -97,6 +108,8 @@ export function patchServiceForStateBaseline(service: ProjectService) {
97108
(logs, project, data) => {
98109
if (project.autoImportProviderHost) autoImportProviderProjects.push(project.autoImportProviderHost);
99110
if (project.noDtsResolutionProject) auxiliaryProjects.push(project.noDtsResolutionProject);
111+
const documentMappers = getSourceMapper(project)?.documentPositionMappers;
112+
if (documentMappers) documentMappers.forEach(mapper => currentMappers.add(mapper));
100113
let projectDiff = newOrDeleted(project, projects, data);
101114
const projectPropertyLogs = [] as string[];
102115
projectDiff = printProperty(PrintPropertyWhen.Always, data, "projectStateVersion", project.projectStateVersion, projectDiff, projectPropertyLogs);
@@ -105,6 +118,15 @@ export function patchServiceForStateBaseline(service: ProjectService) {
105118
projectDiff = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "isClosed", project.isClosed(), projectDiff, projectPropertyLogs);
106119
projectDiff = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "isOrphan", !isBackgroundProject(project) && project.isOrphan(), projectDiff, projectPropertyLogs);
107120
projectDiff = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "noOpenRef", isConfiguredProject(project) && !project.hasOpenRef(), projectDiff, projectPropertyLogs);
121+
projectDiff = printMapPropertyValue(
122+
PrintPropertyWhen.Changed,
123+
data?.documentPositionMappers,
124+
"documentPositionMappers",
125+
getSourceMapper(project)?.documentPositionMappers,
126+
projectDiff,
127+
projectPropertyLogs,
128+
toStringDocumentPostionMapper,
129+
);
108130
projectDiff = printProperty(PrintPropertyWhen.DefinedOrChangedOrNew, data, "autoImportProviderHost", project.autoImportProviderHost, projectDiff, projectPropertyLogs, project.autoImportProviderHost ? project.autoImportProviderHost.projectName : project.autoImportProviderHost);
109131
projectDiff = printProperty(PrintPropertyWhen.DefinedOrChangedOrNew, data, "noDtsResolutionProject", project.noDtsResolutionProject, projectDiff, projectPropertyLogs, project.noDtsResolutionProject ? project.noDtsResolutionProject.projectName : project.noDtsResolutionProject);
110132
return printSetPropertyAndCreateStatementLog(
@@ -129,15 +151,17 @@ export function patchServiceForStateBaseline(service: ProjectService) {
129151
autoImportProviderHost: project.autoImportProviderHost,
130152
noDtsResolutionProject: project.noDtsResolutionProject,
131153
originalConfiguredProjects: project.originalConfiguredProjects && new Set(project.originalConfiguredProjects),
154+
documentPositionMappers: new Map(getSourceMapper(project)?.documentPositionMappers),
132155
}),
133156
);
134157
}
135158

136-
function baselineScriptInfos() {
159+
function baselineScriptInfos(currentMappers: Set<DocumentPositionMapper>) {
137160
return baselineState(
138161
[service.filenameToScriptInfo],
139162
scriptInfos,
140163
(logs, info, data) => {
164+
if (info.documentPositionMapper) currentMappers.add(info.documentPositionMapper);
141165
let infoDiff = newOrDeleted(info, scriptInfos, data);
142166
const infoPropertyLogs = [] as string[];
143167
const isOpen = info.isScriptOpen();
@@ -147,7 +171,7 @@ export function patchServiceForStateBaseline(service: ProjectService) {
147171
infoDiff = printScriptInfoSourceMapFilePath(data, info, infoDiff, infoPropertyLogs);
148172
infoDiff = printProperty(PrintPropertyWhen.DefinedOrChangedOrNew, data, "declarationInfoPath", info.declarationInfoPath, infoDiff, infoPropertyLogs);
149173
infoDiff = printSetPropertyValueWorker(PrintPropertyWhen.DefinedOrChangedOrNew, data?.sourceInfos, "sourceInfos", info.sourceInfos, infoDiff, infoPropertyLogs, identity);
150-
infoDiff = printProperty(PrintPropertyWhen.DefinedOrChangedOrNew, data, "documentPositionMapper", info.documentPositionMapper, infoDiff, infoPropertyLogs, info.documentPositionMapper ? "DocumentPositionMapper" : undefined);
174+
infoDiff = printProperty(PrintPropertyWhen.DefinedOrChangedOrNew, data, "documentPositionMapper", info.documentPositionMapper, infoDiff, infoPropertyLogs, info.documentPositionMapper ? toStringDocumentPostionMapper(info.documentPositionMapper) : undefined);
151175
let defaultProject: Project | undefined;
152176
try {
153177
if (isOpen) defaultProject = info.getDefaultProject();
@@ -182,8 +206,26 @@ export function patchServiceForStateBaseline(service: ProjectService) {
182206
);
183207
}
184208

209+
function baselineDocumentPositionMappers(currentMappers: Set<DocumentPositionMapper>) {
210+
const result = baselineState(
211+
[currentMappers],
212+
documentPositionMappers,
213+
(logs, mapper, data) => {
214+
const mapperDiff = newOrDeleted(mapper, documentPositionMappers, data);
215+
logs.push([
216+
`${toStringDocumentPostionMapper(mapper)}${newOrDeleted(mapper, documentPositionMappers, data)}`,
217+
[" " + mapper.generatedFile!.text.replace(/\n/g, "\n ")],
218+
]);
219+
return mapperDiff;
220+
},
221+
mapper => mapperToId.get(mapper)!,
222+
);
223+
mapperToId.clear();
224+
return result;
225+
}
226+
185227
function baselineState<T, Data>(
186-
currentCaches: (T[] | Map<any, T>)[],
228+
currentCaches: (T[] | Map<any, T> | Set<T>)[],
187229
dataMap: Map<T, Data>,
188230
printWorker: (logs: StateItemLog[], current: T, data: Data | undefined) => Diff,
189231
toData: (current: T) => Data,
@@ -235,8 +277,7 @@ export function patchServiceForStateBaseline(service: ProjectService) {
235277
return printPropertyWorker(
236278
printWhen,
237279
value,
238-
!!data && data[key] !== value,
239-
Diff.Change,
280+
!!data && data[key] !== value ? Diff.Change : Diff.None,
240281
dataDiff,
241282
propertyLogs,
242283
`${key}: ${stringValue === undefined ? value : stringValue}`,
@@ -252,48 +293,92 @@ export function patchServiceForStateBaseline(service: ProjectService) {
252293
propertyLogs: StatePropertyLog[],
253294
toStringPropertyValue: (v: T) => string,
254295
) {
255-
const setPropertyLogs = [] as string[];
256-
let setPropertyDiff = Diff.None;
257-
propertyValue?.forEach(p =>
258-
setPropertyDiff = printPropertyWorker(
296+
return printMapOrSetPropertyValueWorker(
297+
printWhen,
298+
dataValue,
299+
propertyName,
300+
propertyValue,
301+
dataDiff,
302+
propertyLogs,
303+
value => dataDiff !== Diff.New && !dataValue?.has(value) ? Diff.New : Diff.None,
304+
toStringPropertyValue,
305+
);
306+
}
307+
308+
function printMapPropertyValue<T>(
309+
printWhen: PrintPropertyWhen.Changed,
310+
dataValue: Map<string, T> | undefined,
311+
propertyName: string,
312+
propertyValue: Map<string, T> | undefined,
313+
dataDiff: Diff,
314+
propertyLogs: StatePropertyLog[],
315+
toStringPropertyValue: (v: T) => string,
316+
) {
317+
return printMapOrSetPropertyValueWorker(
318+
printWhen,
319+
dataValue,
320+
propertyName,
321+
propertyValue,
322+
dataDiff,
323+
propertyLogs,
324+
(value, key) =>
325+
dataDiff !== Diff.New && dataValue?.get(key) !== value ?
326+
!dataValue?.has(key) ? Diff.New : Diff.Change : Diff.None,
327+
(value, key) => `${key}: ${toStringPropertyValue(value)}`,
328+
);
329+
}
330+
331+
type MapOrSetPropertyKey<T> = T extends Map<infer U, any> ? U : T extends Set<infer U> ? U : never;
332+
type MapOrSetPropertyValue<T> = T extends Map<any, infer U> ? U : T extends Set<infer U> ? U : never;
333+
function printMapOrSetPropertyValueWorker<T extends Map<string, any> | Set<any>>(
334+
printWhen: PrintPropertyWhen.Always | PrintPropertyWhen.DefinedOrChangedOrNew | PrintPropertyWhen.Changed,
335+
dataValue: T | undefined,
336+
propertyName: string,
337+
propertyValue: T | undefined,
338+
dataDiff: Diff,
339+
propertyLogs: StatePropertyLog[],
340+
getPropertyDiff: (value: MapOrSetPropertyValue<T>, key: MapOrSetPropertyKey<T>) => Diff,
341+
toStringPropertyValue: (value: MapOrSetPropertyValue<T>, key: MapOrSetPropertyKey<T>) => string,
342+
) {
343+
// Print changes
344+
const mapPropertyLogs = [] as string[];
345+
let mapPropertyDiff = Diff.None;
346+
propertyValue?.forEach((p, key) =>
347+
mapPropertyDiff = printPropertyWorker(
259348
PrintPropertyWhen.Always,
260349
p,
261-
dataDiff !== Diff.New && !dataValue?.has(p),
262-
Diff.New,
263-
setPropertyDiff,
264-
setPropertyLogs,
265-
` ${toStringPropertyValue(p)}`,
350+
getPropertyDiff(p, key),
351+
mapPropertyDiff,
352+
mapPropertyLogs,
353+
` ${toStringPropertyValue(p, key)}`,
266354
)
267355
);
268-
dataValue?.forEach(p => {
269-
if (propertyValue?.has(p)) return;
270-
setPropertyDiff = Diff.Change;
271-
setPropertyLogs.push(` ${toStringPropertyValue(p)}${Diff.Deleted}`);
356+
dataValue?.forEach((p, key) => {
357+
if (propertyValue?.has(key)) return;
358+
mapPropertyDiff = Diff.Change;
359+
mapPropertyLogs.push(` ${toStringPropertyValue(p, key)}${Diff.Deleted}`);
272360
});
273361
dataDiff = printPropertyWorker(
274362
printWhen,
275363
propertyValue,
276-
!!setPropertyDiff,
277-
Diff.Change,
364+
!!mapPropertyDiff ? Diff.Change : Diff.None,
278365
dataDiff,
279366
propertyLogs,
280367
`${propertyName}: ${propertyValue?.size || 0}`,
281368
);
282-
propertyLogs.push(setPropertyLogs);
369+
if (printWhen !== PrintPropertyWhen.Changed || mapPropertyDiff) propertyLogs.push(mapPropertyLogs);
283370
return dataDiff;
284371
}
285372

286373
function printPropertyWorker(
287374
printWhen: PrintPropertyWhen,
288375
value: any,
289-
propertyChanged: boolean,
290-
propertyChangeDiff: Diff.Change | Diff.New,
376+
propertyDiff: Diff,
291377
dataDiff: Diff,
292378
propertyLogs: StatePropertyLog[],
293379
stringValue: string,
294380
) {
295-
const propertyDiff = propertyChanged ? propertyChangeDiff : Diff.None;
296-
const result = !dataDiff && propertyDiff ? propertyChangeDiff : dataDiff;
381+
const result = !dataDiff && propertyDiff ? Diff.Change : dataDiff;
297382
switch (printWhen) {
298383
case PrintPropertyWhen.Changed:
299384
if (!propertyDiff) return result;
@@ -365,4 +450,18 @@ export function patchServiceForStateBaseline(service: ProjectService) {
365450
identity,
366451
);
367452
}
453+
454+
function toStringDocumentPostionMapper(documentPositionMapper: DocumentPositionMapper) {
455+
if (!documentPositionMapper.generatedFile) return "identitySourceMapConsumer";
456+
let id = documentPositionMappers.get(documentPositionMapper) ||
457+
mapperToId.get(documentPositionMapper);
458+
if (!id) mapperToId.set(documentPositionMapper, id = nextDocumentPositionMapperId++);
459+
return `DocumentPositionMapper${id}`;
460+
}
461+
462+
function getSourceMapper(project: Project) {
463+
return project.projectKind !== ProjectKind.AutoImportProvider ?
464+
project.getLanguageService(/*ensureSynchronized*/ false)?.getSourceMapper() :
465+
undefined;
466+
}
368467
}

src/services/sourcemaps.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export interface SourceMapper {
3636
tryGetSourcePosition(info: DocumentPosition): DocumentPosition | undefined;
3737
tryGetGeneratedPosition(info: DocumentPosition): DocumentPosition | undefined;
3838
clearCache(): void;
39+
documentPositionMappers: Map<string, DocumentPositionMapper>;
3940
}
4041

4142
/** @internal */
@@ -56,7 +57,13 @@ export function getSourceMapper(host: SourceMapperHost): SourceMapper {
5657
const currentDirectory = host.getCurrentDirectory();
5758
const sourceFileLike = new Map<string, SourceFileLike | false>();
5859
const documentPositionMappers = new Map<string, DocumentPositionMapper>();
59-
return { tryGetSourcePosition, tryGetGeneratedPosition, toLineColumnOffset, clearCache };
60+
return {
61+
tryGetSourcePosition,
62+
tryGetGeneratedPosition,
63+
toLineColumnOffset,
64+
clearCache,
65+
documentPositionMappers,
66+
};
6067

6168
function toPath(fileName: string) {
6269
return ts_toPath(fileName, currentDirectory, getCanonicalFileName);

tests/baselines/reference/tsserver/auxiliaryProject/does-not-remove-scrips-from-InferredProject.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ Projects::
146146
/dev/null/inferredProject1* (Inferred) *changed*
147147
projectStateVersion: 1
148148
projectProgramVersion: 1
149+
documentPositionMappers: 1 *changed*
150+
/b.d.ts: identitySourceMapConsumer *new*
149151
noDtsResolutionProject: /dev/null/auxiliaryProject1* *changed*
150152

151153
ScriptInfos::

tests/baselines/reference/tsserver/auxiliaryProject/file-is-added-later-through-finding-definition.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ Projects::
266266
/dev/null/inferredProject1* (Inferred) *changed*
267267
projectStateVersion: 1
268268
projectProgramVersion: 1
269+
documentPositionMappers: 1 *changed*
270+
/user/users/projects/myproject/node_modules/@types/yargs/callback.d.ts: identitySourceMapConsumer *new*
269271
noDtsResolutionProject: /dev/null/auxiliaryProject1* *changed*
270272

271273
ScriptInfos::
@@ -377,6 +379,18 @@ Info seq [hh:mm:ss:mss] response:
377379
}
378380
After request
379381

382+
Projects::
383+
/dev/null/auxiliaryProject1* (Auxiliary)
384+
projectStateVersion: 2
385+
projectProgramVersion: 2
386+
/dev/null/inferredProject1* (Inferred) *changed*
387+
projectStateVersion: 1
388+
projectProgramVersion: 1
389+
documentPositionMappers: 2 *changed*
390+
/user/users/projects/myproject/node_modules/@types/yargs/callback.d.ts: identitySourceMapConsumer
391+
/user/users/projects/myproject/node_modules/@types/yargs/index.d.ts: identitySourceMapConsumer *new*
392+
noDtsResolutionProject: /dev/null/auxiliaryProject1*
393+
380394
ScriptInfos::
381395
/a/lib/lib.d.ts
382396
version: Text-1

tests/baselines/reference/tsserver/auxiliaryProject/resolution-is-reused-from-different-folder.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ Projects::
305305
/dev/null/inferredProject1* (Inferred) *changed*
306306
projectStateVersion: 1
307307
projectProgramVersion: 1
308+
documentPositionMappers: 1 *changed*
309+
/user/users/projects/myproject/node_modules/@types/yargs/callback.d.ts: identitySourceMapConsumer *new*
308310
noDtsResolutionProject: /dev/null/auxiliaryProject1* *changed*
309311

310312
ScriptInfos::

0 commit comments

Comments
 (0)