mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Watch missing map file and update the source mapping accordingly
This commit is contained in:
@@ -342,6 +342,7 @@ namespace ts.server {
|
||||
FailedLookupLocation = "Directory of Failed lookup locations in module resolution",
|
||||
TypeRoots = "Type root directory",
|
||||
NodeModulesForClosedScriptInfo = "node_modules for closed script infos in them",
|
||||
MissingSourceMapFile = "Missing source map file"
|
||||
}
|
||||
|
||||
const enum ConfigFileWatcherStatus {
|
||||
@@ -953,22 +954,25 @@ namespace ts.server {
|
||||
private handleSourceMapProjects(info: ScriptInfo) {
|
||||
// Change in d.ts, update source projects as well
|
||||
if (info.sourceMapFilePath) {
|
||||
const sourceMapFileInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
|
||||
if (sourceMapFileInfo && sourceMapFileInfo.sourceInfos) {
|
||||
this.delayUpdateSourceInfoProjects(sourceMapFileInfo.sourceInfos);
|
||||
if (isString(info.sourceMapFilePath)) {
|
||||
const sourceMapFileInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
|
||||
this.delayUpdateSourceInfoProjects(sourceMapFileInfo && sourceMapFileInfo.sourceInfos);
|
||||
}
|
||||
else {
|
||||
this.delayUpdateSourceInfoProjects(info.sourceMapFilePath.sourceInfos);
|
||||
}
|
||||
}
|
||||
// Change in mapInfo, update declarationProjects and source projects
|
||||
if (info.sourceInfos) {
|
||||
this.delayUpdateSourceInfoProjects(info.sourceInfos);
|
||||
}
|
||||
this.delayUpdateSourceInfoProjects(info.sourceInfos);
|
||||
if (info.declarationInfoPath) {
|
||||
this.delayUpdateProjectsOfScriptInfoPath(info.declarationInfoPath);
|
||||
}
|
||||
}
|
||||
|
||||
private delayUpdateSourceInfoProjects(sourceInfos: Map<true>) {
|
||||
sourceInfos.forEach((_value, path) => this.delayUpdateProjectsOfScriptInfoPath(path as Path));
|
||||
private delayUpdateSourceInfoProjects(sourceInfos: Map<true> | undefined) {
|
||||
if (sourceInfos) {
|
||||
sourceInfos.forEach((_value, path) => this.delayUpdateProjectsOfScriptInfoPath(path as Path));
|
||||
}
|
||||
}
|
||||
|
||||
private delayUpdateProjectsOfScriptInfoPath(path: Path) {
|
||||
@@ -992,6 +996,14 @@ namespace ts.server {
|
||||
// update projects to make sure that set of referenced files is correct
|
||||
this.delayUpdateProjectGraphs(containingProjects);
|
||||
this.handleSourceMapProjects(info);
|
||||
info.closeSourceMapFileWatcher();
|
||||
// need to recalculate source map from declaration file
|
||||
if (info.declarationInfoPath) {
|
||||
const declarationInfo = this.getScriptInfoForPath(info.declarationInfoPath);
|
||||
if (declarationInfo) {
|
||||
declarationInfo.sourceMapFilePath = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2228,32 +2240,43 @@ namespace ts.server {
|
||||
|
||||
/*@internal*/
|
||||
getDocumentPositionMapper(project: Project, generatedFileName: string, sourceFileName?: string): DocumentPositionMapper | undefined {
|
||||
const declarationInfo = this.getOrCreateScriptInfoNotOpenedByClient(generatedFileName, project.currentDirectory, project.directoryStructureHost);
|
||||
// Since declaration info and map file watches arent updating project's directory structure host (which can cache file structure) use host
|
||||
const declarationInfo = this.getOrCreateScriptInfoNotOpenedByClient(generatedFileName, project.currentDirectory, this.host);
|
||||
if (!declarationInfo) return undefined;
|
||||
|
||||
// Try to get from cache
|
||||
declarationInfo.getSnapshot(); // Ensure synchronized
|
||||
if (declarationInfo.sourceMapFilePath !== undefined) {
|
||||
// Doesnt have sourceMap
|
||||
if (!declarationInfo.sourceMapFilePath) return undefined;
|
||||
|
||||
if (isString(declarationInfo.sourceMapFilePath)) {
|
||||
// Ensure mapper is synchronized
|
||||
const mapFileInfo = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath);
|
||||
if (mapFileInfo) {
|
||||
mapFileInfo.getSnapshot();
|
||||
if (mapFileInfo.documentPositionMapper !== undefined) {
|
||||
return mapFileInfo.documentPositionMapper ? mapFileInfo.documentPositionMapper : undefined;
|
||||
const sourceMapFileInfo = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath);
|
||||
if (sourceMapFileInfo) {
|
||||
sourceMapFileInfo.getSnapshot();
|
||||
if (sourceMapFileInfo.documentPositionMapper !== undefined) {
|
||||
sourceMapFileInfo.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo.sourceInfos);
|
||||
return sourceMapFileInfo.documentPositionMapper ? sourceMapFileInfo.documentPositionMapper : undefined;
|
||||
}
|
||||
}
|
||||
declarationInfo.sourceMapFilePath = undefined;
|
||||
}
|
||||
else if (declarationInfo.sourceMapFilePath) {
|
||||
declarationInfo.sourceMapFilePath.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, declarationInfo.sourceMapFilePath.sourceInfos);
|
||||
return undefined;
|
||||
}
|
||||
else if (declarationInfo.sourceMapFilePath !== undefined) {
|
||||
// Doesnt have sourceMap
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Create the mapper
|
||||
declarationInfo.sourceMapFilePath = undefined;
|
||||
let sourceMapFileInfo: ScriptInfo | undefined;
|
||||
let mapFileNameFromDeclarationInfo: string | undefined;
|
||||
|
||||
let readMapFile: ReadMapFile | undefined = mapFileName => {
|
||||
const mapInfo = this.getOrCreateScriptInfoNotOpenedByClient(mapFileName, project.currentDirectory, project.directoryStructureHost);
|
||||
if (!mapInfo) return undefined;
|
||||
let readMapFile: ReadMapFile | undefined = (mapFileName, mapFileNameFromDts) => {
|
||||
const mapInfo = this.getOrCreateScriptInfoNotOpenedByClient(mapFileName, project.currentDirectory, this.host);
|
||||
if (!mapInfo) {
|
||||
mapFileNameFromDeclarationInfo = mapFileNameFromDts;
|
||||
return undefined;
|
||||
}
|
||||
sourceMapFileInfo = mapInfo;
|
||||
const snap = mapInfo.getSnapshot();
|
||||
if (mapInfo.documentPositionMapper !== undefined) return mapInfo.documentPositionMapper;
|
||||
@@ -2271,11 +2294,19 @@ namespace ts.server {
|
||||
declarationInfo.sourceMapFilePath = sourceMapFileInfo.path;
|
||||
sourceMapFileInfo.declarationInfoPath = declarationInfo.path;
|
||||
sourceMapFileInfo.documentPositionMapper = documentPositionMapper || false;
|
||||
if (sourceFileName && documentPositionMapper) {
|
||||
// Attach as source
|
||||
const sourceInfo = this.getOrCreateScriptInfoNotOpenedByClient(sourceFileName, project.currentDirectory, project.directoryStructureHost)!;
|
||||
(sourceMapFileInfo.sourceInfos || (sourceMapFileInfo.sourceInfos = createMap())).set(sourceInfo.path, true);
|
||||
}
|
||||
sourceMapFileInfo.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo.sourceInfos);
|
||||
}
|
||||
else if (mapFileNameFromDeclarationInfo) {
|
||||
declarationInfo.sourceMapFilePath = {
|
||||
declarationInfoPath: declarationInfo.path,
|
||||
watcher: this.addMissingSourceMapFile(
|
||||
project.currentDirectory === this.currentDirectory ?
|
||||
mapFileNameFromDeclarationInfo :
|
||||
getNormalizedAbsolutePath(mapFileNameFromDeclarationInfo, project.currentDirectory),
|
||||
declarationInfo.path
|
||||
),
|
||||
sourceInfos: this.addSourceInfoToSourceMap(sourceFileName, project)
|
||||
};
|
||||
}
|
||||
else {
|
||||
declarationInfo.sourceMapFilePath = false;
|
||||
@@ -2283,6 +2314,34 @@ namespace ts.server {
|
||||
return documentPositionMapper;
|
||||
}
|
||||
|
||||
private addSourceInfoToSourceMap(sourceFileName: string | undefined, project: Project, sourceInfos?: Map<true>) {
|
||||
if (sourceFileName) {
|
||||
// Attach as source
|
||||
const sourceInfo = this.getOrCreateScriptInfoNotOpenedByClient(sourceFileName, project.currentDirectory, project.directoryStructureHost)!;
|
||||
(sourceInfos || (sourceInfos = createMap())).set(sourceInfo.path, true);
|
||||
}
|
||||
return sourceInfos;
|
||||
}
|
||||
|
||||
private addMissingSourceMapFile(mapFileName: string, declarationInfoPath: Path) {
|
||||
const fileWatcher = this.watchFactory.watchFile(
|
||||
this.host,
|
||||
mapFileName,
|
||||
() => {
|
||||
const declarationInfo = this.getScriptInfoForPath(declarationInfoPath);
|
||||
if (declarationInfo && declarationInfo.sourceMapFilePath && !isString(declarationInfo.sourceMapFilePath)) {
|
||||
// Update declaration and source projects
|
||||
this.delayUpdateProjectGraphs(declarationInfo.containingProjects);
|
||||
this.delayUpdateSourceInfoProjects(declarationInfo.sourceMapFilePath.sourceInfos);
|
||||
declarationInfo.closeSourceMapFileWatcher();
|
||||
}
|
||||
},
|
||||
PollingInterval.High,
|
||||
WatchType.MissingSourceMapFile,
|
||||
);
|
||||
return fileWatcher;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getSourceFileLike(fileName: string, projectNameOrProject: string | Project, declarationInfo?: ScriptInfo) {
|
||||
const project = (projectNameOrProject as Project).projectName ? projectNameOrProject as Project : this.findProject(projectNameOrProject as string);
|
||||
@@ -2297,7 +2356,7 @@ namespace ts.server {
|
||||
if (!info) return undefined;
|
||||
|
||||
// Attach as source
|
||||
if (declarationInfo && declarationInfo.sourceMapFilePath && info !== declarationInfo) {
|
||||
if (declarationInfo && isString(declarationInfo.sourceMapFilePath) && info !== declarationInfo) {
|
||||
const sourceMapInfo = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath);
|
||||
if (sourceMapInfo) {
|
||||
(sourceMapInfo.sourceInfos || (sourceMapInfo.sourceInfos = createMap())).set(info.path, true);
|
||||
@@ -2669,11 +2728,18 @@ namespace ts.server {
|
||||
if (!info.isScriptOpen() && info.isOrphan()) {
|
||||
// Otherwise if there is any source info that is alive, this alive too
|
||||
if (!info.sourceMapFilePath) return;
|
||||
const sourceMapInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
|
||||
if (!sourceMapInfo || !sourceMapInfo.sourceInfos) return;
|
||||
if (!forEachKey(sourceMapInfo.sourceInfos, path => {
|
||||
const info = this.getScriptInfoForPath(path as Path)!;
|
||||
return info.isScriptOpen() || !info.isOrphan();
|
||||
let sourceInfos: Map<true> | undefined;
|
||||
if (isString(info.sourceMapFilePath)) {
|
||||
const sourceMapInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
|
||||
sourceInfos = sourceMapInfo && sourceMapInfo.sourceInfos;
|
||||
}
|
||||
else {
|
||||
sourceInfos = info.sourceMapFilePath.sourceInfos;
|
||||
}
|
||||
if (!sourceInfos) return;
|
||||
if (!forEachKey(sourceInfos, path => {
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
return !!info && (info.isScriptOpen() || !info.isOrphan());
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
@@ -2682,11 +2748,18 @@ namespace ts.server {
|
||||
// Retain this script info
|
||||
toRemoveScriptInfos.delete(info.path);
|
||||
if (info.sourceMapFilePath) {
|
||||
// And map file info and source infos
|
||||
toRemoveScriptInfos.delete(info.sourceMapFilePath);
|
||||
const sourceMapInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
|
||||
if (sourceMapInfo && sourceMapInfo.sourceInfos) {
|
||||
sourceMapInfo.sourceInfos.forEach((_value, path) => toRemoveScriptInfos.delete(path));
|
||||
let sourceInfos: Map<true> | undefined;
|
||||
if (isString(info.sourceMapFilePath)) {
|
||||
// And map file info and source infos
|
||||
toRemoveScriptInfos.delete(info.sourceMapFilePath);
|
||||
const sourceMapInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
|
||||
sourceInfos = sourceMapInfo && sourceMapInfo.sourceInfos;
|
||||
}
|
||||
else {
|
||||
sourceInfos = info.sourceMapFilePath.sourceInfos;
|
||||
}
|
||||
if (sourceInfos) {
|
||||
sourceInfos.forEach((_value, path) => toRemoveScriptInfos.delete(path));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -2695,6 +2768,7 @@ namespace ts.server {
|
||||
// if there are not projects that include this script info - delete it
|
||||
this.stopWatchingScriptInfo(info);
|
||||
this.deleteScriptInfo(info);
|
||||
info.closeSourceMapFileWatcher();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace ts.server {
|
||||
|
||||
private resetSourceMapInfo() {
|
||||
this.info.sourceFileLike = undefined;
|
||||
this.info.closeSourceMapFileWatcher();
|
||||
this.info.sourceMapFilePath = undefined;
|
||||
this.info.declarationInfoPath = undefined;
|
||||
this.info.sourceInfos = undefined;
|
||||
@@ -280,6 +281,13 @@ namespace ts.server {
|
||||
sourceFile: SourceFile;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface SourceMapFileWatcher {
|
||||
declarationInfoPath: Path;
|
||||
watcher: FileWatcher;
|
||||
sourceInfos?: Map<true>;
|
||||
}
|
||||
|
||||
export class ScriptInfo {
|
||||
/**
|
||||
* All projects that include this file
|
||||
@@ -309,7 +317,7 @@ namespace ts.server {
|
||||
sourceFileLike?: SourceFileLike;
|
||||
|
||||
/*@internal*/
|
||||
sourceMapFilePath?: Path | false;
|
||||
sourceMapFilePath?: Path | SourceMapFileWatcher | false;
|
||||
|
||||
// Present on sourceMapFile info
|
||||
/*@internal*/
|
||||
@@ -606,5 +614,13 @@ namespace ts.server {
|
||||
getLineInfo(): LineInfo {
|
||||
return this.textStorage.getLineInfo();
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
closeSourceMapFileWatcher() {
|
||||
if (this.sourceMapFilePath && !isString(this.sourceMapFilePath)) {
|
||||
closeFileWatcherOf(this.sourceMapFilePath);
|
||||
this.sourceMapFilePath = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace ts {
|
||||
* string | undefined to contents of map file to create DocumentPositionMapper from it
|
||||
* DocumentPositionMapper | false to give back cached DocumentPositionMapper
|
||||
*/
|
||||
export type ReadMapFile = (mapFileName: string) => string | undefined | DocumentPositionMapper | false;
|
||||
export type ReadMapFile = (mapFileName: string, mapFileNameFromDts: string | undefined) => string | undefined | DocumentPositionMapper | false;
|
||||
|
||||
export function getDocumentPositionMapper(
|
||||
host: DocumentPositionMapperHost,
|
||||
@@ -155,9 +155,10 @@ namespace ts {
|
||||
possibleMapLocations.push(mapFileName);
|
||||
}
|
||||
possibleMapLocations.push(generatedFileName + ".map");
|
||||
const originalMapFileName = mapFileName && getNormalizedAbsolutePath(mapFileName, getDirectoryPath(generatedFileName));
|
||||
for (const location of possibleMapLocations) {
|
||||
const mapFileName = getNormalizedAbsolutePath(location, getDirectoryPath(generatedFileName));
|
||||
const mapFileContents = readMapFile(mapFileName);
|
||||
const mapFileContents = readMapFile(mapFileName, originalMapFileName);
|
||||
if (isString(mapFileContents)) {
|
||||
return convertDocumentToSourceMapper(host, mapFileContents, mapFileName);
|
||||
}
|
||||
|
||||
@@ -10806,8 +10806,11 @@ fn5();
|
||||
const configFiles = openFiles.map(openFile => `${getDirectoryPath(openFile.path)}/tsconfig.json`);
|
||||
const openInfos = openFiles.map(f => f.path);
|
||||
const otherWatchedFiles = configFiles;
|
||||
function openTsFile() {
|
||||
function openTsFile(onHostCreate?: (host: TestServerHost) => void) {
|
||||
const host = createHost(files, [mainConfig.path]);
|
||||
if (onHostCreate) {
|
||||
onHostCreate(host);
|
||||
}
|
||||
const session = createSession(host);
|
||||
openFilesForSession([...openFiles, randomFile], session);
|
||||
return { host, session };
|
||||
@@ -10821,8 +10824,19 @@ fn5();
|
||||
});
|
||||
}
|
||||
|
||||
function verifyInfos(session: TestSession, host: TestServerHost, minusDtsMapAndSource?: true) {
|
||||
verifyInfosWithRandom(session, host, openInfos, minusDtsMapAndSource ? closedInfos.filter(f => f !== dependencyTs.path && f.toLowerCase() !== dtsMapPath) : closedInfos, otherWatchedFiles);
|
||||
function verifyInfos(session: TestSession, host: TestServerHost) {
|
||||
verifyInfosWithRandom(session, host, openInfos, closedInfos, otherWatchedFiles);
|
||||
}
|
||||
|
||||
function verifyInfosWhenNoMapFile(session: TestSession, host: TestServerHost, dependencyTsOK?: true) {
|
||||
const dtsMapClosedInfo = firstDefined(closedInfos, f => f.toLowerCase() === dtsMapPath ? f : undefined);
|
||||
verifyInfosWithRandom(
|
||||
session,
|
||||
host,
|
||||
openInfos,
|
||||
closedInfos.filter(f => f !== dtsMapClosedInfo && (dependencyTsOK || f !== dependencyTs.path)),
|
||||
dtsMapClosedInfo ? otherWatchedFiles.concat(dtsMapClosedInfo) : otherWatchedFiles
|
||||
);
|
||||
}
|
||||
|
||||
function verifyDocumentPositionMapper(session: TestSession, dependencyMap: server.ScriptInfo, documentPositionMapper: server.ScriptInfo["documentPositionMapper"], notEqual?: true) {
|
||||
@@ -10841,14 +10855,20 @@ fn5();
|
||||
return { response, expectedResponse, expectedNoMapResponse };
|
||||
}
|
||||
|
||||
function verifyAllFnActionWorker(session: TestSession, verifyAction: (result: ReturnType<typeof action>, dtsInfo: server.ScriptInfo) => void) {
|
||||
function firstAction(session: TestSession) {
|
||||
actionGetters.forEach(actionGetter => action(actionGetter, 1, session));
|
||||
}
|
||||
|
||||
function verifyAllFnActionWorker(session: TestSession, verifyAction: (result: ReturnType<typeof action>, dtsInfo: server.ScriptInfo, isFirst: boolean) => void) {
|
||||
// action
|
||||
let isFirst = true;
|
||||
for (const actionGetter of actionGetters) {
|
||||
for (let fn = 1; fn <= 5; fn++) {
|
||||
const result = action(actionGetter, fn, session);
|
||||
const dtsInfo = session.getProjectService().filenameToScriptInfo.get(dtsPath);
|
||||
assert.isDefined(dtsInfo);
|
||||
verifyAction(result, dtsInfo!);
|
||||
verifyAction(result, dtsInfo!, isFirst);
|
||||
isFirst = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10861,13 +10881,11 @@ fn5();
|
||||
documentPositionMapper?: server.ScriptInfo["documentPositionMapper"]
|
||||
) {
|
||||
// action
|
||||
let isFirst = true;
|
||||
verifyAllFnActionWorker(session, ({ response, expectedResponse }, dtsInfo) => {
|
||||
verifyAllFnActionWorker(session, ({ response, expectedResponse }, dtsInfo, isFirst) => {
|
||||
assert.deepEqual(response, expectedResponse);
|
||||
verifyInfos(session, host);
|
||||
assert.equal(dtsInfo.sourceMapFilePath, dtsMapPath);
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
if (dependencyMap) {
|
||||
verifyDocumentPositionMapper(session, dependencyMap, documentPositionMapper, firstDocumentPositionMapperNotEquals);
|
||||
documentPositionMapper = dependencyMap.documentPositionMapper;
|
||||
@@ -10886,15 +10904,26 @@ fn5();
|
||||
|
||||
function verifyAllFnActionWithNoMap(
|
||||
session: TestSession,
|
||||
host: TestServerHost
|
||||
host: TestServerHost,
|
||||
dependencyTsOK?: true
|
||||
) {
|
||||
let sourceMapFilePath: server.ScriptInfo["sourceMapFilePath"];
|
||||
// action
|
||||
verifyAllFnActionWorker(session, ({ response, expectedResponse, expectedNoMapResponse }, dtsInfo) => {
|
||||
verifyAllFnActionWorker(session, ({ response, expectedResponse, expectedNoMapResponse }, dtsInfo, isFirst) => {
|
||||
assert.deepEqual(response, expectedNoMapResponse && verifier.length ? expectedNoMapResponse : expectedResponse);
|
||||
verifyInfos(session, host, /*minusDtsMapAndSource*/ true);
|
||||
assert.isFalse(dtsInfo.sourceMapFilePath);
|
||||
verifyInfosWhenNoMapFile(session, host, dependencyTsOK);
|
||||
assert.isUndefined(session.getProjectService().filenameToScriptInfo.get(dtsMapPath));
|
||||
if (isFirst) {
|
||||
assert.isNotString(dtsInfo.sourceMapFilePath);
|
||||
assert.isNotFalse(dtsInfo.sourceMapFilePath);
|
||||
assert.isDefined(dtsInfo.sourceMapFilePath);
|
||||
sourceMapFilePath = dtsInfo.sourceMapFilePath;
|
||||
}
|
||||
else {
|
||||
assert.equal(dtsInfo.sourceMapFilePath, sourceMapFilePath);
|
||||
}
|
||||
});
|
||||
return sourceMapFilePath;
|
||||
}
|
||||
|
||||
function verifyScenarioWithChangesWorker(
|
||||
@@ -10905,7 +10934,7 @@ fn5();
|
||||
const { host, session } = openTsFile();
|
||||
|
||||
// Create DocumentPositionMapper
|
||||
actionGetters.forEach(actionGetter => action(actionGetter, 1, session));
|
||||
firstAction(session);
|
||||
const dependencyMap = session.getProjectService().filenameToScriptInfo.get(dtsMapPath)!;
|
||||
const documentPositionMapper = dependencyMap.documentPositionMapper;
|
||||
|
||||
@@ -10934,10 +10963,7 @@ fn5();
|
||||
});
|
||||
}
|
||||
|
||||
it(mainScenario, () => {
|
||||
const { host, session } = openTsFile();
|
||||
checkProject(session);
|
||||
|
||||
function verifyMainScenarioAndScriptInfoCollection(session: TestSession, host: TestServerHost) {
|
||||
// Main scenario action
|
||||
const { dependencyMap, documentPositionMapper } = verifyAllFnAction(session, host);
|
||||
checkProject(session);
|
||||
@@ -10953,6 +10979,28 @@ fn5();
|
||||
closeFilesForSession([...openFiles, randomFile], session);
|
||||
openFilesForSession([randomFile], session);
|
||||
verifyOnlyRandomInfos(session, host);
|
||||
}
|
||||
|
||||
function verifyMainScenarioAndScriptInfoCollectionWithNoMap(session: TestSession, host: TestServerHost, dependencyTsOKInScenario?: true) {
|
||||
// Main scenario action
|
||||
verifyAllFnActionWithNoMap(session, host, dependencyTsOKInScenario);
|
||||
|
||||
// Collecting at this point retains dependency.d.ts and map watcher
|
||||
closeFilesForSession([randomFile], session);
|
||||
openFilesForSession([randomFile], session);
|
||||
verifyInfosWhenNoMapFile(session, host);
|
||||
|
||||
// Closing open file, removes dependencies too
|
||||
closeFilesForSession([...openFiles, randomFile], session);
|
||||
openFilesForSession([randomFile], session);
|
||||
verifyOnlyRandomInfos(session, host);
|
||||
}
|
||||
|
||||
it(mainScenario, () => {
|
||||
const { host, session } = openTsFile();
|
||||
checkProject(session);
|
||||
|
||||
verifyMainScenarioAndScriptInfoCollection(session, host);
|
||||
});
|
||||
|
||||
describe("when usage file changes, document position mapper doesnt change", () => {
|
||||
@@ -10963,7 +11011,7 @@ fn5();
|
||||
})));
|
||||
});
|
||||
|
||||
describe("when dependency file changes, document position mapper doesnt change", () => {
|
||||
describe("when dependency .d.ts changes, document position mapper doesnt change", () => {
|
||||
// Edit dts to add new fn
|
||||
verifyScenarioWithChanges(host => host.writeFile(
|
||||
dtsLocation,
|
||||
@@ -10983,15 +11031,34 @@ fn5();
|
||||
), /*afterActionDocumentPositionMapperNotEquals*/ true);
|
||||
});
|
||||
|
||||
it("when map file is not present", () => {
|
||||
const host = createHost(files, [mainConfig.path]);
|
||||
host.deleteFile(dtsMapLocation);
|
||||
describe("when map file is not present", () => {
|
||||
it(mainScenario, () => {
|
||||
const { host, session } = openTsFile(host => host.deleteFile(dtsMapLocation));
|
||||
checkProject(session);
|
||||
|
||||
const session = createSession(host);
|
||||
openFilesForSession([...openFiles, randomFile], session);
|
||||
checkProject(session);
|
||||
verifyMainScenarioAndScriptInfoCollectionWithNoMap(session, host);
|
||||
});
|
||||
|
||||
verifyAllFnActionWithNoMap(session, host);
|
||||
it("when map file is created", () => {
|
||||
let dtsMapContents: string | undefined;
|
||||
const { host, session } = openTsFile(host => {
|
||||
dtsMapContents = host.readFile(dtsMapLocation)!;
|
||||
host.deleteFile(dtsMapLocation);
|
||||
});
|
||||
firstAction(session);
|
||||
|
||||
host.writeFile(dtsMapLocation, dtsMapContents!);
|
||||
verifyMainScenarioAndScriptInfoCollection(session, host);
|
||||
});
|
||||
|
||||
it("when map file is deleted", () => {
|
||||
const { host, session } = openTsFile();
|
||||
firstAction(session);
|
||||
|
||||
// The dependency file is deleted when orphan files are collected
|
||||
host.deleteFile(dtsMapLocation);
|
||||
verifyMainScenarioAndScriptInfoCollectionWithNoMap(session, host, /*dependencyTsOKInScenario*/ true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user