@@ -10692,7 +10692,11 @@ export function fn5() { }
1069210692 const mainTs: File = {
1069310693 path: `${mainLocation}/main.ts`,
1069410694 content: `import {
10695- fn1, fn2, fn3, fn4, fn5
10695+ fn1,
10696+ fn2,
10697+ fn3,
10698+ fn4,
10699+ fn5
1069610700} from '../dependency/fns'
1069710701
1069810702fn1();
@@ -10739,9 +10743,9 @@ fn5();
1073910743 }
1074010744
1074110745 // Returns request and expected Response, expected response when no map file
10742- type SessionAction<Req = protocol.Request, Response = {}> = [Partial<Req>, Response, Response?];
10746+ type SessionAction<Req = protocol.Request, Response = {}> = [Partial<Req>, Response, Response?, Response? ];
1074310747 function gotoDefintinionFromMainTs(fn: number): SessionAction<protocol.DefinitionAndBoundSpanRequest, protocol.DefinitionInfoAndBoundSpan> {
10744- const startSpan = { line: fn + 4 , offset: 1 };
10748+ const startSpan = { line: fn + 8 , offset: 1 };
1074510749 const textSpan: protocol.TextSpan = { start: startSpan, end: { line: startSpan.line, offset: startSpan.offset + 3 } };
1074610750 const definitionSpan: protocol.FileSpan = { file: dependencyTs.path, start: { line: fn, offset: 17 }, end: { line: fn, offset: 20 } };
1074710751 const declareSpaceLength = "declare ".length;
@@ -10751,12 +10755,19 @@ fn5();
1075110755 arguments: { file: mainTs.path, ...startSpan }
1075210756 },
1075310757 {
10758+ // To dependency
1075410759 definitions: [definitionSpan],
1075510760 textSpan
1075610761 },
1075710762 {
10763+ // To the dts
1075810764 definitions: [{ file: dtsPath, start: { line: fn, offset: definitionSpan.start.offset + declareSpaceLength }, end: { line: fn, offset: definitionSpan.end.offset + declareSpaceLength } }],
1075910765 textSpan
10766+ },
10767+ {
10768+ // To import declaration
10769+ definitions: [{ file: mainTs.path, start: { line: fn + 1, offset: 5 }, end: { line: fn + 1, offset: 8 } }],
10770+ textSpan
1076010771 }
1076110772 ];
1076210773 }
@@ -10816,11 +10827,16 @@ fn5();
1081610827 return { host, session };
1081710828 }
1081810829
10819- function checkProject(session: TestSession) {
10830+ function checkProject(session: TestSession, noDts?: true ) {
1082010831 const service = session.getProjectService();
1082110832 checkNumberOfProjects(service, { configuredProjects: 1 + verifier.length });
1082210833 configFiles.forEach((configFile, index) => {
10823- checkProjectActualFiles(service.configuredProjects.get(configFile)!, expectedProjectActualFiles[index]);
10834+ checkProjectActualFiles(
10835+ service.configuredProjects.get(configFile)!,
10836+ noDts ?
10837+ expectedProjectActualFiles[index].filter(f => f.toLowerCase() !== dtsPath) :
10838+ expectedProjectActualFiles[index]
10839+ );
1082410840 });
1082510841 }
1082610842
@@ -10839,6 +10855,21 @@ fn5();
1083910855 );
1084010856 }
1084110857
10858+ function verifyInfosWhenNoDtsFile(session: TestSession, host: TestServerHost) {
10859+ const dtsMapClosedInfo = firstDefined(closedInfos, f => f.toLowerCase() === dtsMapPath ? f : undefined);
10860+ const dtsClosedInfo = firstDefined(closedInfos, f => f.toLowerCase() === dtsPath ? f : undefined);
10861+ verifyInfosWithRandom(
10862+ session,
10863+ host,
10864+ openInfos,
10865+ closedInfos.filter(f => f !== dtsMapClosedInfo && f !== dtsClosedInfo && f !== dependencyTs.path),
10866+ // When project actual file contains dts, it needs to be watched
10867+ dtsClosedInfo && verifier.length === 1 && expectedProjectActualFiles[0].some(f => f.toLowerCase() === dtsPath) ?
10868+ otherWatchedFiles.concat(dtsClosedInfo) :
10869+ otherWatchedFiles
10870+ );
10871+ }
10872+
1084210873 function verifyDocumentPositionMapper(session: TestSession, dependencyMap: server.ScriptInfo, documentPositionMapper: server.ScriptInfo["documentPositionMapper"], notEqual?: true) {
1084310874 assert.strictEqual(session.getProjectService().filenameToScriptInfo.get(dtsMapPath), dependencyMap);
1084410875 if (notEqual) {
@@ -10850,24 +10881,29 @@ fn5();
1085010881 }
1085110882
1085210883 function action(actionGetter: SessionActionGetter, fn: number, session: TestSession) {
10853- const [req, expectedResponse, expectedNoMapResponse] = actionGetter(fn);
10884+ const [req, expectedResponse, expectedNoMapResponse, expectedNoDtsResponse ] = actionGetter(fn);
1085410885 const { response } = session.executeCommandSeq(req);
10855- return { response, expectedResponse, expectedNoMapResponse };
10886+ return { response, expectedResponse, expectedNoMapResponse, expectedNoDtsResponse };
1085610887 }
1085710888
1085810889 function firstAction(session: TestSession) {
1085910890 actionGetters.forEach(actionGetter => action(actionGetter, 1, session));
1086010891 }
1086110892
10862- function verifyAllFnActionWorker(session: TestSession, verifyAction: (result: ReturnType<typeof action>, dtsInfo: server.ScriptInfo, isFirst: boolean) => void) {
10893+ function verifyAllFnActionWorker(session: TestSession, verifyAction: (result: ReturnType<typeof action>, dtsInfo: server.ScriptInfo | undefined , isFirst: boolean) => void, dtsAbsent?: true ) {
1086310894 // action
1086410895 let isFirst = true;
1086510896 for (const actionGetter of actionGetters) {
1086610897 for (let fn = 1; fn <= 5; fn++) {
1086710898 const result = action(actionGetter, fn, session);
1086810899 const dtsInfo = session.getProjectService().filenameToScriptInfo.get(dtsPath);
10869- assert.isDefined(dtsInfo);
10870- verifyAction(result, dtsInfo!, isFirst);
10900+ if (dtsAbsent) {
10901+ assert.isUndefined(dtsInfo);
10902+ }
10903+ else {
10904+ assert.isDefined(dtsInfo);
10905+ }
10906+ verifyAction(result, dtsInfo, isFirst);
1087110907 isFirst = false;
1087210908 }
1087310909 }
@@ -10884,7 +10920,7 @@ fn5();
1088410920 verifyAllFnActionWorker(session, ({ response, expectedResponse }, dtsInfo, isFirst) => {
1088510921 assert.deepEqual(response, expectedResponse);
1088610922 verifyInfos(session, host);
10887- assert.equal(dtsInfo.sourceMapFilePath, dtsMapPath);
10923+ assert.equal(dtsInfo! .sourceMapFilePath, dtsMapPath);
1088810924 if (isFirst) {
1088910925 if (dependencyMap) {
1089010926 verifyDocumentPositionMapper(session, dependencyMap, documentPositionMapper, firstDocumentPositionMapperNotEquals);
@@ -10910,22 +10946,33 @@ fn5();
1091010946 let sourceMapFilePath: server.ScriptInfo["sourceMapFilePath"];
1091110947 // action
1091210948 verifyAllFnActionWorker(session, ({ response, expectedResponse, expectedNoMapResponse }, dtsInfo, isFirst) => {
10913- assert.deepEqual(response, expectedNoMapResponse && verifier.length ? expectedNoMapResponse : expectedResponse);
10949+ assert.deepEqual(response, expectedNoMapResponse || expectedResponse);
1091410950 verifyInfosWhenNoMapFile(session, host, dependencyTsOK);
1091510951 assert.isUndefined(session.getProjectService().filenameToScriptInfo.get(dtsMapPath));
1091610952 if (isFirst) {
10917- assert.isNotString(dtsInfo.sourceMapFilePath);
10918- assert.isNotFalse(dtsInfo.sourceMapFilePath);
10919- assert.isDefined(dtsInfo.sourceMapFilePath);
10920- sourceMapFilePath = dtsInfo.sourceMapFilePath;
10953+ assert.isNotString(dtsInfo! .sourceMapFilePath);
10954+ assert.isNotFalse(dtsInfo! .sourceMapFilePath);
10955+ assert.isDefined(dtsInfo! .sourceMapFilePath);
10956+ sourceMapFilePath = dtsInfo! .sourceMapFilePath;
1092110957 }
1092210958 else {
10923- assert.equal(dtsInfo.sourceMapFilePath, sourceMapFilePath);
10959+ assert.equal(dtsInfo! .sourceMapFilePath, sourceMapFilePath);
1092410960 }
1092510961 });
1092610962 return sourceMapFilePath;
1092710963 }
1092810964
10965+ function verifyAllFnActionWithNoDts(
10966+ session: TestSession,
10967+ host: TestServerHost
10968+ ) {
10969+ // action
10970+ verifyAllFnActionWorker(session, ({ response, expectedResponse, expectedNoDtsResponse }) => {
10971+ assert.deepEqual(response, expectedNoDtsResponse || expectedResponse);
10972+ verifyInfosWhenNoDtsFile(session, host);
10973+ }, /*dtsAbsent*/ true);
10974+ }
10975+
1092910976 function verifyScenarioWithChangesWorker(
1093010977 change: (host: TestServerHost, session: TestSession) => void,
1093110978 afterActionDocumentPositionMapperNotEquals: true | undefined,
@@ -10996,6 +11043,21 @@ fn5();
1099611043 verifyOnlyRandomInfos(session, host);
1099711044 }
1099811045
11046+ function verifyMainScenarioAndScriptInfoCollectionWithNoDts(session: TestSession, host: TestServerHost) {
11047+ // Main scenario action
11048+ verifyAllFnActionWithNoDts(session, host);
11049+
11050+ // Collecting at this point retains dependency.d.ts and map watcher
11051+ closeFilesForSession([randomFile], session);
11052+ openFilesForSession([randomFile], session);
11053+ verifyInfosWhenNoDtsFile(session, host);
11054+
11055+ // Closing open file, removes dependencies too
11056+ closeFilesForSession([...openFiles, randomFile], session);
11057+ openFilesForSession([randomFile], session);
11058+ verifyOnlyRandomInfos(session, host);
11059+ }
11060+
1099911061 it(mainScenario, () => {
1100011062 const { host, session } = openTsFile();
1100111063 checkProject(session);
@@ -11060,13 +11122,22 @@ fn5();
1106011122 verifyMainScenarioAndScriptInfoCollectionWithNoMap(session, host, /*dependencyTsOKInScenario*/ true);
1106111123 });
1106211124 });
11125+
11126+ describe("when .d.ts file is not present", () => {
11127+ it(mainScenario, () => {
11128+ const { host, session } = openTsFile(host => host.deleteFile(dtsLocation));
11129+ checkProject(session, /*noDts*/ true);
11130+
11131+ verifyMainScenarioAndScriptInfoCollectionWithNoDts(session, host);
11132+ });
11133+ });
1106311134 }
1106411135
1106511136 const usageVerifier: DocumentPositionMapperVerifier = [
1106611137 /*openFile*/ mainTs,
1106711138 /*expectedProjectActualFiles*/[mainTs.path, libFile.path, mainConfig.path, dtsPath],
1106811139 /*actionGetter*/ gotoDefintinionFromMainTs,
11069- /*openFileLastLine*/ 10
11140+ /*openFileLastLine*/ 14
1107011141 ];
1107111142 describe("from project that uses dependency", () => {
1107211143 const closedInfos = [dependencyTs.path, dependencyConfig.path, libFile.path, dtsPath, dtsMapLocation];
0 commit comments