Skip to content

Commit 9e8b3d9

Browse files
authored
Merge pull request #14846 from Microsoft/dev/billti/port14809ToMaster
Port 14809 to master
2 parents a9d8df2 + 21c9547 commit 9e8b3d9

File tree

4 files changed

+66
-10
lines changed

4 files changed

+66
-10
lines changed

src/harness/unittests/tsserverProjectSystem.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,41 @@ namespace ts.projectSystem {
10071007
checkProjectRootFiles(projectService.configuredProjects[0], [commonFile1.path, commonFile2.path]);
10081008
});
10091009

1010+
it("should disable features when the files are too large", () => {
1011+
const file1 = {
1012+
path: "/a/b/f1.js",
1013+
content: "let x =1;",
1014+
fileSize: 10 * 1024 * 1024
1015+
};
1016+
const file2 = {
1017+
path: "/a/b/f2.js",
1018+
content: "let y =1;",
1019+
fileSize: 6 * 1024 * 1024
1020+
};
1021+
const file3 = {
1022+
path: "/a/b/f3.js",
1023+
content: "let y =1;",
1024+
fileSize: 6 * 1024 * 1024
1025+
};
1026+
1027+
const proj1name = "proj1", proj2name = "proj2", proj3name = "proj3";
1028+
1029+
const host = createServerHost([file1, file2, file3]);
1030+
const projectService = createProjectService(host);
1031+
1032+
projectService.openExternalProject({ rootFiles: toExternalFiles([file1.path]), options: {}, projectFileName: proj1name });
1033+
const proj1 = projectService.findProject(proj1name);
1034+
assert.isTrue(proj1.languageServiceEnabled);
1035+
1036+
projectService.openExternalProject({ rootFiles: toExternalFiles([file2.path]), options: {}, projectFileName: proj2name });
1037+
const proj2 = projectService.findProject(proj2name);
1038+
assert.isTrue(proj2.languageServiceEnabled);
1039+
1040+
projectService.openExternalProject({ rootFiles: toExternalFiles([file3.path]), options: {}, projectFileName: proj3name });
1041+
const proj3 = projectService.findProject(proj3name);
1042+
assert.isFalse(proj3.languageServiceEnabled);
1043+
});
1044+
10101045
it("should use only one inferred project if 'useOneInferredProject' is set", () => {
10111046
const file1 = {
10121047
path: "/a/b/main.ts",

src/server/editorServices.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ namespace ts.server {
254254

255255
private compilerOptionsForInferredProjects: CompilerOptions;
256256
private compileOnSaveForInferredProjects: boolean;
257+
private readonly projectToSizeMap: Map<number> = createMap<number>();
257258
private readonly directoryWatchers: DirectoryWatchers;
258259
private readonly throttledOperations: ThrottledOperations;
259260

@@ -563,9 +564,11 @@ namespace ts.server {
563564
switch (project.projectKind) {
564565
case ProjectKind.External:
565566
removeItemFromSet(this.externalProjects, <ExternalProject>project);
567+
this.projectToSizeMap.delete((project as ExternalProject).externalProjectName);
566568
break;
567569
case ProjectKind.Configured:
568570
removeItemFromSet(this.configuredProjects, <ConfiguredProject>project);
571+
this.projectToSizeMap.delete((project as ConfiguredProject).canonicalConfigFilePath);
569572
break;
570573
case ProjectKind.Inferred:
571574
removeItemFromSet(this.inferredProjects, <InferredProject>project);
@@ -852,10 +855,15 @@ namespace ts.server {
852855
return { success: true, projectOptions, configFileErrors: errors };
853856
}
854857

855-
private exceededTotalSizeLimitForNonTsFiles<T>(options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader<T>) {
858+
private exceededTotalSizeLimitForNonTsFiles<T>(name: string, options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader<T>) {
856859
if (options && options.disableSizeLimit || !this.host.getFileSize) {
857860
return false;
858861
}
862+
863+
let availableSpace = maxProgramSizeForNonTsFiles;
864+
this.projectToSizeMap.set(name, 0);
865+
this.projectToSizeMap.forEach(val => (availableSpace -= (val || 0)));
866+
859867
let totalNonTsFileSize = 0;
860868
for (const f of fileNames) {
861869
const fileName = propertyReader.getFileName(f);
@@ -864,9 +872,16 @@ namespace ts.server {
864872
}
865873
totalNonTsFileSize += this.host.getFileSize(fileName);
866874
if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) {
875+
// Keep the size as zero since it's disabled
867876
return true;
868877
}
869878
}
879+
880+
if (totalNonTsFileSize > availableSpace) {
881+
return true;
882+
}
883+
884+
this.projectToSizeMap.set(name, totalNonTsFileSize);
870885
return false;
871886
}
872887

@@ -877,7 +892,7 @@ namespace ts.server {
877892
this,
878893
this.documentRegistry,
879894
compilerOptions,
880-
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader),
895+
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader),
881896
options.compileOnSave === undefined ? true : options.compileOnSave);
882897

883898
this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typeAcquisition, /*configFileErrors*/ undefined);
@@ -897,7 +912,7 @@ namespace ts.server {
897912
}
898913

899914
private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) {
900-
const sizeLimitExceeded = this.exceededTotalSizeLimitForNonTsFiles(projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
915+
const sizeLimitExceeded = this.exceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
901916
const project = new ConfiguredProject(
902917
configFileName,
903918
this,
@@ -1050,7 +1065,7 @@ namespace ts.server {
10501065
return configFileErrors;
10511066
}
10521067

1053-
if (this.exceededTotalSizeLimitForNonTsFiles(projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) {
1068+
if (this.exceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) {
10541069
project.setCompilerOptions(projectOptions.compilerOptions);
10551070
if (!project.languageServiceEnabled) {
10561071
// language service is already disabled
@@ -1414,7 +1429,7 @@ namespace ts.server {
14141429
if (externalProject) {
14151430
if (!tsConfigFiles) {
14161431
const compilerOptions = convertCompilerOptions(proj.options);
1417-
if (this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, proj.rootFiles, externalFilePropertyReader)) {
1432+
if (this.exceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader)) {
14181433
externalProject.disableLanguageService();
14191434
}
14201435
else {

src/server/project.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ namespace ts.server {
10311031

10321032
export class ExternalProject extends Project {
10331033
private typeAcquisition: TypeAcquisition;
1034-
constructor(externalProjectName: string,
1034+
constructor(public externalProjectName: string,
10351035
projectService: ProjectService,
10361036
documentRegistry: ts.DocumentRegistry,
10371037
compilerOptions: CompilerOptions,

src/server/session.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,14 @@ namespace ts.server {
2525
return ((1e9 * seconds) + nanoseconds) / 1000000.0;
2626
}
2727

28-
function shouldSkipSematicCheck(project: Project) {
29-
return (project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) && project.isJsOnlyProject();
28+
function shouldSkipSemanticCheck(project: Project) {
29+
if (project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) {
30+
return project.isJsOnlyProject();
31+
}
32+
else {
33+
// For configured projects, require that skipLibCheck be set also
34+
return project.getCompilerOptions().skipLibCheck && project.isJsOnlyProject();
35+
}
3036
}
3137

3238
interface FileStart {
@@ -447,7 +453,7 @@ namespace ts.server {
447453
private semanticCheck(file: NormalizedPath, project: Project) {
448454
try {
449455
let diags: Diagnostic[] = [];
450-
if (!shouldSkipSematicCheck(project)) {
456+
if (!shouldSkipSemanticCheck(project)) {
451457
diags = project.getLanguageService().getSemanticDiagnostics(file);
452458
}
453459

@@ -555,7 +561,7 @@ namespace ts.server {
555561

556562
private getDiagnosticsWorker(args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
557563
const { project, file } = this.getFileAndProject(args);
558-
if (isSemantic && shouldSkipSematicCheck(project)) {
564+
if (isSemantic && shouldSkipSemanticCheck(project)) {
559565
return [];
560566
}
561567
const scriptInfo = project.getScriptInfoForNormalizedPath(file);

0 commit comments

Comments
 (0)