Skip to content

Commit 69a8504

Browse files
authored
Merge pull request #17791 from Microsoft/dynamicFiles
Introduce the concept of a Dynamic File
2 parents 555a742 + 6f6c3c2 commit 69a8504

File tree

4 files changed

+28
-21
lines changed

4 files changed

+28
-21
lines changed

src/server/builder.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace ts.server {
66

77
export function shouldEmitFile(scriptInfo: ScriptInfo) {
8-
return !scriptInfo.hasMixedContent;
8+
return !scriptInfo.hasMixedContent && !scriptInfo.isDynamic;
99
}
1010

1111
/**
@@ -188,7 +188,7 @@ namespace ts.server {
188188
*/
189189
getFilesAffectedBy(scriptInfo: ScriptInfo): string[] {
190190
const info = this.getOrCreateFileInfo(scriptInfo.path);
191-
const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName];
191+
const singleFileResult = scriptInfo.hasMixedContent || scriptInfo.isDynamic ? [] : [scriptInfo.fileName];
192192
if (info.updateShapeSignature()) {
193193
const options = this.project.getCompilerOptions();
194194
// If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
@@ -303,7 +303,7 @@ namespace ts.server {
303303
getFilesAffectedBy(scriptInfo: ScriptInfo): string[] {
304304
this.ensureProjectDependencyGraphUpToDate();
305305

306-
const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName];
306+
const singleFileResult = scriptInfo.hasMixedContent || scriptInfo.isDynamic ? [] : [scriptInfo.fileName];
307307
const fileInfo = this.getFileInfo(scriptInfo.path);
308308
if (!fileInfo || !fileInfo.updateShapeSignature()) {
309309
return singleFileResult;

src/server/editorServices.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,21 @@ namespace ts.server {
239239
getFileName(f: T): string;
240240
getScriptKind(f: T): ScriptKind;
241241
hasMixedContent(f: T, extraFileExtensions: JsFileExtensionInfo[]): boolean;
242+
isDynamicFile(f: T): boolean;
242243
}
243244

244245
const fileNamePropertyReader: FilePropertyReader<string> = {
245246
getFileName: x => x,
246247
getScriptKind: _ => undefined,
247248
hasMixedContent: (fileName, extraFileExtensions) => some(extraFileExtensions, ext => ext.isMixedContent && fileExtensionIs(fileName, ext.extension)),
249+
isDynamicFile: x => x[0] === "^",
248250
};
249251

250252
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
251253
getFileName: x => x.fileName,
252254
getScriptKind: x => tryConvertScriptKindName(x.scriptKind),
253-
hasMixedContent: x => x.hasMixedContent
255+
hasMixedContent: x => x.hasMixedContent,
256+
isDynamicFile: x => x.fileName[0] === "^",
254257
};
255258

256259
function findProjectByName<T extends Project>(projectName: string, projects: T[]): T {
@@ -1210,15 +1213,16 @@ namespace ts.server {
12101213
private addFilesToProjectAndUpdateGraph<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, clientFileName: string, typeAcquisition: TypeAcquisition, configFileErrors: ReadonlyArray<Diagnostic>): void {
12111214
let errors: Diagnostic[];
12121215
for (const f of files) {
1213-
const rootFilename = propertyReader.getFileName(f);
1216+
const rootFileName = propertyReader.getFileName(f);
12141217
const scriptKind = propertyReader.getScriptKind(f);
12151218
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
1216-
if (this.host.fileExists(rootFilename)) {
1217-
const info = this.getOrCreateScriptInfoForNormalizedPath(toNormalizedPath(rootFilename), /*openedByClient*/ clientFileName === rootFilename, /*fileContent*/ undefined, scriptKind, hasMixedContent);
1219+
const isDynamicFile = propertyReader.isDynamicFile(f);
1220+
if (isDynamicFile || this.host.fileExists(rootFileName)) {
1221+
const info = this.getOrCreateScriptInfoForNormalizedPath(toNormalizedPath(rootFileName), /*openedByClient*/ clientFileName === rootFileName, /*fileContent*/ undefined, scriptKind, hasMixedContent, isDynamicFile);
12181222
project.addRoot(info);
12191223
}
12201224
else {
1221-
(errors || (errors = [])).push(createFileNotFoundDiagnostic(rootFilename));
1225+
(errors || (errors = [])).push(createFileNotFoundDiagnostic(rootFileName));
12221226
}
12231227
}
12241228
project.setProjectErrors(concatenate(configFileErrors, errors));
@@ -1248,7 +1252,8 @@ namespace ts.server {
12481252
let rootFilesChanged = false;
12491253
for (const f of newUncheckedFiles) {
12501254
const newRootFile = propertyReader.getFileName(f);
1251-
if (!this.host.fileExists(newRootFile)) {
1255+
const isDynamic = propertyReader.isDynamicFile(f);
1256+
if (!isDynamic && !this.host.fileExists(newRootFile)) {
12521257
(projectErrors || (projectErrors = [])).push(createFileNotFoundDiagnostic(newRootFile));
12531258
continue;
12541259
}
@@ -1259,7 +1264,7 @@ namespace ts.server {
12591264
if (!scriptInfo) {
12601265
const scriptKind = propertyReader.getScriptKind(f);
12611266
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
1262-
scriptInfo = this.getOrCreateScriptInfoForNormalizedPath(normalizedPath, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent);
1267+
scriptInfo = this.getOrCreateScriptInfoForNormalizedPath(normalizedPath, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, isDynamic);
12631268
}
12641269
}
12651270
newRootScriptInfos.push(scriptInfo);
@@ -1443,17 +1448,17 @@ namespace ts.server {
14431448

14441449
watchClosedScriptInfo(info: ScriptInfo) {
14451450
// do not watch files with mixed content - server doesn't know how to interpret it
1446-
if (!info.hasMixedContent) {
1451+
if (!info.hasMixedContent && !info.isDynamic) {
14471452
const { fileName } = info;
14481453
info.setWatcher(this.host.watchFile(fileName, _ => this.onSourceFileChanged(fileName)));
14491454
}
14501455
}
14511456

1452-
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean) {
1457+
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, isDynamic?: boolean) {
14531458
let info = this.getScriptInfoForNormalizedPath(fileName);
14541459
if (!info) {
1455-
if (openedByClient || this.host.fileExists(fileName)) {
1456-
info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent);
1460+
if (openedByClient || isDynamic || this.host.fileExists(fileName)) {
1461+
info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent, isDynamic);
14571462

14581463
this.filenameToScriptInfo.set(info.path, info);
14591464

@@ -1463,6 +1468,7 @@ namespace ts.server {
14631468
fileContent = this.host.readFile(fileName) || "";
14641469
}
14651470
}
1471+
14661472
else {
14671473
this.watchClosedScriptInfo(info);
14681474
}

src/server/scriptInfo.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,12 @@ namespace ts.server {
156156
private readonly host: ServerHost,
157157
readonly fileName: NormalizedPath,
158158
readonly scriptKind: ScriptKind,
159-
public hasMixedContent = false) {
159+
public hasMixedContent = false,
160+
public isDynamic = false) {
160161

161162
this.path = toPath(fileName, host.getCurrentDirectory(), createGetCanonicalFileName(host.useCaseSensitiveFileNames));
162163
this.textStorage = new TextStorage(host, fileName);
163-
if (hasMixedContent) {
164+
if (hasMixedContent || isDynamic) {
164165
this.textStorage.reload("");
165166
}
166167
this.scriptKind = scriptKind
@@ -180,7 +181,7 @@ namespace ts.server {
180181

181182
public close() {
182183
this.isOpen = false;
183-
this.textStorage.useText(this.hasMixedContent ? "" : undefined);
184+
this.textStorage.useText(this.hasMixedContent || this.isDynamic ? "" : undefined);
184185
this.markContainingProjectsAsDirty();
185186
}
186187

@@ -307,7 +308,7 @@ namespace ts.server {
307308
}
308309

309310
reloadFromFile(tempFileName?: NormalizedPath) {
310-
if (this.hasMixedContent) {
311+
if (this.hasMixedContent || this.isDynamic) {
311312
this.reload("");
312313
}
313314
else {
@@ -354,4 +355,4 @@ namespace ts.server {
354355
return this.scriptKind === ScriptKind.JS || this.scriptKind === ScriptKind.JSX;
355356
}
356357
}
357-
}
358+
}

src/server/utilities.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ namespace ts.server {
9595
};
9696
}
9797

98-
export function mergeMapLikes(target: MapLike<any>, source: MapLike <any>): void {
98+
export function mergeMapLikes(target: MapLike<any>, source: MapLike<any>): void {
9999
for (const key in source) {
100100
if (hasProperty(source, key)) {
101101
target[key] = source[key];
@@ -299,4 +299,4 @@ namespace ts.server {
299299
deleted(oldItems[oldIndex++]);
300300
}
301301
}
302-
}
302+
}

0 commit comments

Comments
 (0)