Merge pull request #6545 from zhengbli/supportJsconfig
Add support for jsconfig.json in language service
This commit is contained in:
commit
931d162620
|
@ -493,8 +493,8 @@ namespace ts {
|
|||
* @param basePath A root directory to resolve relative path entries in the config
|
||||
* file to. e.g. outDir
|
||||
*/
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}): ParsedCommandLine {
|
||||
const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath);
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string): ParsedCommandLine {
|
||||
const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath, configFileName);
|
||||
|
||||
const options = extend(existingOptions, optionsFromJsonConfigFile);
|
||||
return {
|
||||
|
@ -523,7 +523,7 @@ namespace ts {
|
|||
for (const extension of supportedExtensions) {
|
||||
const filesInDirWithExtension = host.readDirectory(basePath, extension, exclude);
|
||||
for (const fileName of filesInDirWithExtension) {
|
||||
// .ts extension would read the .d.ts extension files too but since .d.ts is lower priority extension,
|
||||
// .ts extension would read the .d.ts extension files too but since .d.ts is lower priority extension,
|
||||
// lets pick them when its turn comes up
|
||||
if (extension === ".ts" && fileExtensionIs(fileName, ".d.ts")) {
|
||||
continue;
|
||||
|
@ -547,10 +547,15 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string): { options: CompilerOptions, errors: Diagnostic[] } {
|
||||
export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions, errors: Diagnostic[] } {
|
||||
const options: CompilerOptions = {};
|
||||
const errors: Diagnostic[] = [];
|
||||
|
||||
if (configFileName && getBaseFileName(configFileName) === "jsconfig.json") {
|
||||
options.module = ModuleKind.CommonJS;
|
||||
options.allowJs = true;
|
||||
}
|
||||
|
||||
if (!jsonOptions) {
|
||||
return { options, errors };
|
||||
}
|
||||
|
|
|
@ -340,7 +340,7 @@ namespace ts {
|
|||
if (sys.watchDirectory && configFileName) {
|
||||
const directory = ts.getDirectoryPath(configFileName);
|
||||
directoryWatcher = sys.watchDirectory(
|
||||
// When the configFileName is just "tsconfig.json", the watched directory should be
|
||||
// When the configFileName is just "tsconfig.json", the watched directory should be
|
||||
// the current direcotry; if there is a given "project" parameter, then the configFileName
|
||||
// is an absolute file name.
|
||||
directory == "" ? "." : directory,
|
||||
|
|
|
@ -120,7 +120,7 @@ namespace ts.server {
|
|||
if (!resolution) {
|
||||
const existingResolution = currentResolutionsInFile && ts.lookUp(currentResolutionsInFile, moduleName);
|
||||
if (moduleResolutionIsValid(existingResolution)) {
|
||||
// ok, it is safe to use existing module resolution results
|
||||
// ok, it is safe to use existing module resolution results
|
||||
resolution = existingResolution;
|
||||
}
|
||||
else {
|
||||
|
@ -145,8 +145,8 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
if (resolution.resolvedModule) {
|
||||
// TODO: consider checking failedLookupLocations
|
||||
// TODO: use lastCheckTime to track expiration for module name resolution
|
||||
// TODO: consider checking failedLookupLocations
|
||||
// TODO: use lastCheckTime to track expiration for module name resolution
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -483,7 +483,7 @@ namespace ts.server {
|
|||
openFileRootsConfigured: ScriptInfo[] = [];
|
||||
// a path to directory watcher map that detects added tsconfig files
|
||||
directoryWatchersForTsconfig: ts.Map<FileWatcher> = {};
|
||||
// count of how many projects are using the directory watcher. If the
|
||||
// count of how many projects are using the directory watcher. If the
|
||||
// number becomes 0 for a watcher, then we should close it.
|
||||
directoryWatchersRefCount: ts.Map<number> = {};
|
||||
hostConfiguration: HostConfiguration;
|
||||
|
@ -564,11 +564,11 @@ namespace ts.server {
|
|||
// We check if the project file list has changed. If so, we update the project.
|
||||
if (!arrayIsEqualTo(currentRootFiles && currentRootFiles.sort(), newRootFiles && newRootFiles.sort())) {
|
||||
// For configured projects, the change is made outside the tsconfig file, and
|
||||
// it is not likely to affect the project for other files opened by the client. We can
|
||||
// it is not likely to affect the project for other files opened by the client. We can
|
||||
// just update the current project.
|
||||
this.updateConfiguredProject(project);
|
||||
|
||||
// Call updateProjectStructure to clean up inferred projects we may have
|
||||
// Call updateProjectStructure to clean up inferred projects we may have
|
||||
// created for the new files
|
||||
this.updateProjectStructure();
|
||||
}
|
||||
|
@ -792,8 +792,8 @@ namespace ts.server {
|
|||
* @param info The file that has been closed or newly configured
|
||||
*/
|
||||
closeOpenFile(info: ScriptInfo) {
|
||||
// Closing file should trigger re-reading the file content from disk. This is
|
||||
// because the user may chose to discard the buffer content before saving
|
||||
// Closing file should trigger re-reading the file content from disk. This is
|
||||
// because the user may chose to discard the buffer content before saving
|
||||
// to the disk, and the server's version of the file can be out of sync.
|
||||
info.svc.reloadFromFile(info.fileName);
|
||||
|
||||
|
@ -891,8 +891,8 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
/**
|
||||
* This function is to update the project structure for every projects.
|
||||
* It is called on the premise that all the configured projects are
|
||||
* This function is to update the project structure for every projects.
|
||||
* It is called on the premise that all the configured projects are
|
||||
* up to date.
|
||||
*/
|
||||
updateProjectStructure() {
|
||||
|
@ -946,7 +946,7 @@ namespace ts.server {
|
|||
|
||||
if (rootFile.defaultProject && rootFile.defaultProject.isConfiguredProject()) {
|
||||
// If the root file has already been added into a configured project,
|
||||
// meaning the original inferred project is gone already.
|
||||
// meaning the original inferred project is gone already.
|
||||
if (!rootedProject.isConfiguredProject()) {
|
||||
this.removeProject(rootedProject);
|
||||
}
|
||||
|
@ -1026,10 +1026,16 @@ namespace ts.server {
|
|||
// the newly opened file.
|
||||
findConfigFile(searchPath: string): string {
|
||||
while (true) {
|
||||
const fileName = ts.combinePaths(searchPath, "tsconfig.json");
|
||||
if (this.host.fileExists(fileName)) {
|
||||
return fileName;
|
||||
const tsconfigFileName = ts.combinePaths(searchPath, "tsconfig.json");
|
||||
if (this.host.fileExists(tsconfigFileName)) {
|
||||
return tsconfigFileName;
|
||||
}
|
||||
|
||||
const jsconfigFileName = ts.combinePaths(searchPath, "jsconfig.json");
|
||||
if (this.host.fileExists(jsconfigFileName)) {
|
||||
return jsconfigFileName;
|
||||
}
|
||||
|
||||
const parentPath = ts.getDirectoryPath(searchPath);
|
||||
if (parentPath === searchPath) {
|
||||
break;
|
||||
|
@ -1053,9 +1059,9 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
/**
|
||||
* This function tries to search for a tsconfig.json for the given file. If we found it,
|
||||
* This function tries to search for a tsconfig.json for the given file. If we found it,
|
||||
* we first detect if there is already a configured project created for it: if so, we re-read
|
||||
* the tsconfig file content and update the project; otherwise we create a new one.
|
||||
* the tsconfig file content and update the project; otherwise we create a new one.
|
||||
*/
|
||||
openOrUpdateConfiguredProjectForFile(fileName: string) {
|
||||
const searchPath = ts.normalizePath(getDirectoryPath(fileName));
|
||||
|
@ -1180,7 +1186,7 @@ namespace ts.server {
|
|||
return { succeeded: false, error: rawConfig.error };
|
||||
}
|
||||
else {
|
||||
const parsedCommandLine = ts.parseJsonConfigFileContent(rawConfig.config, this.host, dirPath);
|
||||
const parsedCommandLine = ts.parseJsonConfigFileContent(rawConfig.config, this.host, dirPath, /*existingOptions*/ {}, configFilename);
|
||||
Debug.assert(!!parsedCommandLine.fileNames);
|
||||
|
||||
if (parsedCommandLine.errors && (parsedCommandLine.errors.length > 0)) {
|
||||
|
@ -1259,7 +1265,7 @@ namespace ts.server {
|
|||
info = this.openFile(fileName, /*openedByClient*/ false);
|
||||
}
|
||||
else {
|
||||
// if the root file was opened by client, it would belong to either
|
||||
// if the root file was opened by client, it would belong to either
|
||||
// openFileRoots or openFileReferenced.
|
||||
if (info.isOpen) {
|
||||
if (this.openFileRoots.indexOf(info) >= 0) {
|
||||
|
|
|
@ -946,7 +946,8 @@ namespace ts {
|
|||
};
|
||||
}
|
||||
|
||||
const configFile = parseJsonConfigFileContent(result.config, this.host, getDirectoryPath(normalizeSlashes(fileName)));
|
||||
const normalizedFileName = normalizeSlashes(fileName);
|
||||
const configFile = parseJsonConfigFileContent(result.config, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
|
||||
|
||||
return {
|
||||
options: configFile.options,
|
||||
|
|
Loading…
Reference in a new issue