Skip to content

Commit 12971d2

Browse files
committed
Merge branch 'tsconfigMixedContentSupportRedux' into tsconfigMixedContentSupport
2 parents 891173c + 464bc0e commit 12971d2

File tree

12 files changed

+57
-43
lines changed

12 files changed

+57
-43
lines changed

src/compiler/commandLineParser.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ namespace ts {
827827
* @param basePath A root directory to resolve relative path entries in the config
828828
* file to. e.g. outDir
829829
*/
830-
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string, resolutionStack: Path[] = [], mixedContentFileExtensions: string[] = []): ParsedCommandLine {
830+
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string, resolutionStack: Path[] = [], fileExtensionMap: FileExtensionMap = {}): ParsedCommandLine {
831831
const errors: Diagnostic[] = [];
832832
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
833833
const resolvedPath = toPath(configFileName || "", basePath, getCanonicalFileName);
@@ -964,7 +964,7 @@ namespace ts {
964964
includeSpecs = ["**/*"];
965965
}
966966

967-
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors, mixedContentFileExtensions);
967+
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors, fileExtensionMap);
968968

969969
if (result.fileNames.length === 0 && !hasProperty(json, "files") && resolutionStack.length === 0) {
970970
errors.push(
@@ -1166,7 +1166,7 @@ namespace ts {
11661166
* @param host The host used to resolve files and directories.
11671167
* @param errors An array for diagnostic reporting.
11681168
*/
1169-
function matchFileNames(fileNames: string[], include: string[], exclude: string[], basePath: string, options: CompilerOptions, host: ParseConfigHost, errors: Diagnostic[], mixedContentFileExtensions: string[]): ExpandResult {
1169+
function matchFileNames(fileNames: string[], include: string[], exclude: string[], basePath: string, options: CompilerOptions, host: ParseConfigHost, errors: Diagnostic[], fileExtensionMap: FileExtensionMap): ExpandResult {
11701170
basePath = normalizePath(basePath);
11711171

11721172
// The exclude spec list is converted into a regular expression, which allows us to quickly
@@ -1200,7 +1200,7 @@ namespace ts {
12001200

12011201
// Rather than requery this for each file and filespec, we query the supported extensions
12021202
// once and store it on the expansion context.
1203-
const supportedExtensions = getSupportedExtensions(options, mixedContentFileExtensions);
1203+
const supportedExtensions = getSupportedExtensions(options, fileExtensionMap);
12041204

12051205
// Literal files are always included verbatim. An "include" or "exclude" specification cannot
12061206
// remove a literal file.

src/compiler/core.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,8 +1942,16 @@ namespace ts {
19421942
export const supportedJavascriptExtensions = [".js", ".jsx"];
19431943
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
19441944

1945-
export function getSupportedExtensions(options?: CompilerOptions, mixedContentFileExtensions?: string[]): string[] {
1946-
return options && options.allowJs ? concatenate(allSupportedExtensions, mixedContentFileExtensions) : supportedTypeScriptExtensions;
1945+
export function getSupportedExtensions(options?: CompilerOptions, fileExtensionMap?: FileExtensionMap): string[] {
1946+
let typeScriptHostExtensions: string[] = [];
1947+
let allHostExtensions: string[] = [];
1948+
if (fileExtensionMap) {
1949+
allHostExtensions = concatenate(concatenate(fileExtensionMap.javaScript, fileExtensionMap.typeScript), fileExtensionMap.mixedContent);
1950+
typeScriptHostExtensions = fileExtensionMap.typeScript;
1951+
}
1952+
const allTypeScriptExtensions = concatenate(supportedTypeScriptExtensions, typeScriptHostExtensions);
1953+
const allExtensions = concatenate(allSupportedExtensions, allHostExtensions);
1954+
return options && options.allowJs ? allExtensions : allTypeScriptExtensions;
19471955
}
19481956

19491957
export function hasJavaScriptFileExtension(fileName: string) {
@@ -1954,10 +1962,10 @@ namespace ts {
19541962
return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension));
19551963
}
19561964

1957-
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, mixedContentFileExtensions?: string[]) {
1965+
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, fileExtensionMap?: FileExtensionMap) {
19581966
if (!fileName) { return false; }
19591967

1960-
for (const extension of getSupportedExtensions(compilerOptions, mixedContentFileExtensions)) {
1968+
for (const extension of getSupportedExtensions(compilerOptions, fileExtensionMap)) {
19611969
if (fileExtensionIs(fileName, extension)) {
19621970
return true;
19631971
}

src/compiler/program.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ namespace ts {
285285
return resolutions;
286286
}
287287

288-
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, mixedContentFileExtensions?: string[]): Program {
288+
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, fileExtensionMap?: FileExtensionMap): Program {
289289
let program: Program;
290290
let files: SourceFile[] = [];
291291
let commonSourceDirectory: string;
@@ -320,7 +320,7 @@ namespace ts {
320320
let skipDefaultLib = options.noLib;
321321
const programDiagnostics = createDiagnosticCollection();
322322
const currentDirectory = host.getCurrentDirectory();
323-
const supportedExtensions = getSupportedExtensions(options, mixedContentFileExtensions);
323+
const supportedExtensions = getSupportedExtensions(options, fileExtensionMap);
324324

325325
// Map storing if there is emit blocking diagnostics for given input
326326
const hasEmitBlockingDiagnostics = createFileMap<boolean>(getCanonicalFileName);

src/compiler/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3075,6 +3075,12 @@ namespace ts {
30753075
ThisProperty
30763076
}
30773077

3078+
export interface FileExtensionMap {
3079+
javaScript?: string[];
3080+
typeScript?: string[];
3081+
mixedContent?: string[];
3082+
}
3083+
30783084
export interface DiagnosticMessage {
30793085
key: string;
30803086
category: DiagnosticCategory;

src/harness/unittests/tsserverProjectSystem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,7 @@ namespace ts.projectSystem {
14641464
checkProjectActualFiles(projectService.configuredProjects[0], [file1.path]);
14651465

14661466
// Specify .html extension as mixed content
1467-
const configureHostRequest = makeSessionRequest<protocol.ConfigureRequestArguments>(CommandNames.Configure, { mixedContentFileExtensions: [".html"] });
1467+
const configureHostRequest = makeSessionRequest<protocol.ConfigureRequestArguments>(CommandNames.Configure, { fileExtensionMap: { mixedContent: [".html"] } });
14681468
session.executeCommand(configureHostRequest).response;
14691469

14701470
// HTML file still not included in the project as it is closed

src/server/editorServices.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ namespace ts.server {
108108
export interface HostConfiguration {
109109
formatCodeOptions: FormatCodeSettings;
110110
hostInfo: string;
111-
mixedContentFileExtensions?: string[];
111+
fileExtensionMap?: FileExtensionMap;
112112
}
113113

114114
interface ConfigFileConversionResult {
@@ -133,13 +133,13 @@ namespace ts.server {
133133
interface FilePropertyReader<T> {
134134
getFileName(f: T): string;
135135
getScriptKind(f: T): ScriptKind;
136-
hasMixedContent(f: T, mixedContentFileExtensions: string[]): boolean;
136+
hasMixedContent(f: T, mixedContentExtensions: string[]): boolean;
137137
}
138138

139139
const fileNamePropertyReader: FilePropertyReader<string> = {
140140
getFileName: x => x,
141141
getScriptKind: _ => undefined,
142-
hasMixedContent: (fileName, mixedContentFileExtensions) => forEach(mixedContentFileExtensions, extension => fileExtensionIs(fileName, extension))
142+
hasMixedContent: (fileName, mixedContentExtensions) => forEach(mixedContentExtensions, extension => fileExtensionIs(fileName, extension))
143143
};
144144

145145
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
@@ -284,7 +284,7 @@ namespace ts.server {
284284
this.hostConfiguration = {
285285
formatCodeOptions: getDefaultFormatCodeSettings(this.host),
286286
hostInfo: "Unknown host",
287-
mixedContentFileExtensions: []
287+
fileExtensionMap: {}
288288
};
289289

290290
this.documentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames, host.getCurrentDirectory());
@@ -488,7 +488,7 @@ namespace ts.server {
488488
// If a change was made inside "folder/file", node will trigger the callback twice:
489489
// one with the fileName being "folder/file", and the other one with "folder".
490490
// We don't respond to the second one.
491-
if (fileName && !ts.isSupportedSourceFileName(fileName, project.getCompilerOptions(), this.hostConfiguration.mixedContentFileExtensions)) {
491+
if (fileName && !ts.isSupportedSourceFileName(fileName, project.getCompilerOptions(), this.hostConfiguration.fileExtensionMap)) {
492492
return;
493493
}
494494

@@ -810,7 +810,7 @@ namespace ts.server {
810810
/*existingOptions*/ {},
811811
configFilename,
812812
/*resolutionStack*/ [],
813-
this.hostConfiguration.mixedContentFileExtensions);
813+
this.hostConfiguration.fileExtensionMap);
814814

815815
if (parsedCommandLine.errors.length) {
816816
errors = concatenate(errors, parsedCommandLine.errors);
@@ -914,7 +914,7 @@ namespace ts.server {
914914
for (const f of files) {
915915
const rootFilename = propertyReader.getFileName(f);
916916
const scriptKind = propertyReader.getScriptKind(f);
917-
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.mixedContentFileExtensions);
917+
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.fileExtensionMap.mixedContent);
918918
if (this.host.fileExists(rootFilename)) {
919919
const info = this.getOrCreateScriptInfoForNormalizedPath(toNormalizedPath(rootFilename), /*openedByClient*/ clientFileName == rootFilename, /*fileContent*/ undefined, scriptKind, hasMixedContent);
920920
project.addRoot(info);
@@ -960,7 +960,7 @@ namespace ts.server {
960960
rootFilesChanged = true;
961961
if (!scriptInfo) {
962962
const scriptKind = propertyReader.getScriptKind(f);
963-
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.mixedContentFileExtensions);
963+
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.fileExtensionMap.mixedContent);
964964
scriptInfo = this.getOrCreateScriptInfoForNormalizedPath(normalizedPath, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent);
965965
}
966966
}
@@ -1144,9 +1144,9 @@ namespace ts.server {
11441144
mergeMaps(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions));
11451145
this.logger.info("Format host information updated");
11461146
}
1147-
if (args.mixedContentFileExtensions) {
1148-
this.hostConfiguration.mixedContentFileExtensions = args.mixedContentFileExtensions;
1149-
this.logger.info("Host mixed content file extensions updated");
1147+
if (args.fileExtensionMap) {
1148+
this.hostConfiguration.fileExtensionMap = args.fileExtensionMap;
1149+
this.logger.info("Host file extension mappings updated");
11501150
}
11511151
}
11521152
}

src/server/lsHost.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace ts.server {
66
export class LSHost implements ts.LanguageServiceHost, ModuleResolutionHost {
77
private compilationSettings: ts.CompilerOptions;
8-
private mixedContentFileExtensions: string[];
8+
private fileExtensionMap: FileExtensionMap;
99
private readonly resolvedModuleNames = createFileMap<Map<ResolvedModuleWithFailedLookupLocations>>();
1010
private readonly resolvedTypeReferenceDirectives = createFileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
1111
private readonly getCanonicalFileName: (fileName: string) => string;
@@ -144,8 +144,8 @@ namespace ts.server {
144144
return this.compilationSettings;
145145
}
146146

147-
getMixedContentFileExtensions() {
148-
return this.mixedContentFileExtensions;
147+
getFileExtensionMap() {
148+
return this.fileExtensionMap;
149149
}
150150

151151
useCaseSensitiveFileNames() {
@@ -237,8 +237,8 @@ namespace ts.server {
237237
this.compilationSettings = opt;
238238
}
239239

240-
setMixedContentFileExtensions(mixedContentFileExtensions: string[]) {
241-
this.mixedContentFileExtensions = mixedContentFileExtensions || [];
240+
setFileExtensionMap(fileExtensionMap: FileExtensionMap) {
241+
this.fileExtensionMap = fileExtensionMap || {};
242242
}
243243
}
244244
}

src/server/project.ts

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

255255
this.lsHost = new LSHost(this.projectService.host, this, this.projectService.cancellationToken);
256256
this.lsHost.setCompilationSettings(this.compilerOptions);
257-
this.lsHost.setMixedContentFileExtensions(this.projectService.hostConfiguration.mixedContentFileExtensions);
257+
this.lsHost.setFileExtensionMap(this.projectService.hostConfiguration.fileExtensionMap);
258258

259259
this.languageService = ts.createLanguageService(this.lsHost, this.documentRegistry);
260260
this.noSemanticFeaturesLanguageService = createNoSemanticFeaturesWrapper(this.languageService);

src/server/protocol.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -992,9 +992,9 @@ namespace ts.server.protocol {
992992
formatOptions?: FormatCodeSettings;
993993

994994
/**
995-
* List of host's supported mixed content file extensions
995+
* The host's supported file extension mappings
996996
*/
997-
mixedContentFileExtensions?: string[];
997+
fileExtensionMap?: FileExtensionMap;
998998
}
999999

10001000
/**

src/services/completions.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,14 @@ namespace ts.Completions {
271271
const span = getDirectoryFragmentTextSpan((<StringLiteral>node).text, node.getStart() + 1);
272272
let entries: CompletionEntry[];
273273
if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) {
274-
const mixedContentFileExtensions = host.getMixedContentFileExtensions ? host.getMixedContentFileExtensions() : [];
274+
const fileExtensionMap = host.getFileExtensionMap ? host.getFileExtensionMap() : {};
275275
if (compilerOptions.rootDirs) {
276276
entries = getCompletionEntriesForDirectoryFragmentWithRootDirs(
277-
compilerOptions.rootDirs, literalValue, scriptDirectory, getSupportedExtensions(compilerOptions, mixedContentFileExtensions), /*includeExtensions*/false, span, scriptPath);
277+
compilerOptions.rootDirs, literalValue, scriptDirectory, getSupportedExtensions(compilerOptions, fileExtensionMap), /*includeExtensions*/false, span, scriptPath);
278278
}
279279
else {
280280
entries = getCompletionEntriesForDirectoryFragment(
281-
literalValue, scriptDirectory, getSupportedExtensions(compilerOptions, mixedContentFileExtensions), /*includeExtensions*/false, span, scriptPath);
281+
literalValue, scriptDirectory, getSupportedExtensions(compilerOptions, fileExtensionMap), /*includeExtensions*/false, span, scriptPath);
282282
}
283283
}
284284
else {
@@ -412,8 +412,8 @@ namespace ts.Completions {
412412
let result: CompletionEntry[];
413413

414414
if (baseUrl) {
415-
const mixedContentFileExtensions = host.getMixedContentFileExtensions ? host.getMixedContentFileExtensions() : [];
416-
const fileExtensions = getSupportedExtensions(compilerOptions, mixedContentFileExtensions);
415+
const fileExtensionMap = host.getFileExtensionMap ? host.getFileExtensionMap() : {};
416+
const fileExtensions = getSupportedExtensions(compilerOptions, fileExtensionMap);
417417
const projectDir = compilerOptions.project || host.getCurrentDirectory();
418418
const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl);
419419
result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/false, span);
@@ -590,8 +590,8 @@ namespace ts.Completions {
590590
if (kind === "path") {
591591
// Give completions for a relative path
592592
const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
593-
const mixedContentFileExtensions = host.getMixedContentFileExtensions ? host.getMixedContentFileExtensions() : [];
594-
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions, mixedContentFileExtensions), /*includeExtensions*/true, span, sourceFile.path);
593+
const fileExtensionMap = host.getFileExtensionMap ? host.getFileExtensionMap() : {};
594+
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions, fileExtensionMap), /*includeExtensions*/true, span, sourceFile.path);
595595
}
596596
else {
597597
// Give completions based on the typings available

0 commit comments

Comments
 (0)