Use project root as the current directory whenever possible to create the project

This commit is contained in:
Sheetal Nandi 2017-09-26 17:29:53 -07:00
parent ec95921315
commit fad71d3dc6
10 changed files with 78 additions and 59 deletions

View File

@ -984,11 +984,18 @@ namespace ts {
return true;
}
if (defaultLibraryPath && defaultLibraryPath.length !== 0) {
return containsPath(defaultLibraryPath, file.path, currentDirectory, /*ignoreCase*/ !host.useCaseSensitiveFileNames());
if (!options.noLib) {
return false;
}
return compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo;
// If '--lib' is not specified, include default library file according to '--target'
// otherwise, using options specified in '--lib' instead of '--target' default library file
if (!options.lib) {
return compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo;
}
else {
return forEach(options.lib, libFileName => compareStrings(file.fileName, combinePaths(defaultLibraryPath, libFileName), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo);
}
}
function getDiagnosticsProducingTypeChecker() {

View File

@ -567,7 +567,7 @@ namespace ts.projectSystem {
path: "/a/b/file3.js",
content: "console.log('file3');"
};
const externalProjectName = "externalproject";
const externalProjectName = "/a/b/externalproject";
const host = createServerHost([file1, file2, file3, libFile]);
const session = createSession(host);
const projectService = session.getProjectService();

View File

@ -16,8 +16,8 @@ namespace ts.server {
directoryExists: () => false,
getDirectories: () => [],
createDirectory: noop,
getExecutingFilePath(): string { return void 0; },
getCurrentDirectory(): string { return void 0; },
getExecutingFilePath(): string { return ""; },
getCurrentDirectory(): string { return ""; },
getEnvironmentVariable(): string { return ""; },
readDirectory() { return []; },
exit: noop,

View File

@ -148,9 +148,8 @@ namespace ts.server {
const { emitSkipped, outputFiles } = this.project.getFileEmitOutput(fileInfo.scriptInfo, /*emitOnlyDtsFiles*/ false);
if (!emitSkipped) {
const projectRootPath = this.project.getProjectRootPath();
for (const outputFile of outputFiles) {
const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, projectRootPath ? projectRootPath : getDirectoryPath(scriptInfo.fileName));
const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, this.project.currentDirectory);
writeFile(outputFileAbsoluteFileName, outputFile.text, outputFile.writeByteOrderMark);
}
}

View File

@ -417,7 +417,7 @@ namespace ts.server {
this.globalPlugins = opts.globalPlugins || emptyArray;
this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray;
this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads;
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.host.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation;
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation;
Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService");
@ -442,6 +442,16 @@ namespace ts.server {
this.documentRegistry = createDocumentRegistry(this.host.useCaseSensitiveFileNames, this.host.getCurrentDirectory());
}
/*@internal*/
getExecutingFilePath() {
return this.getNormalizedAbsolutePath(this.host.getExecutingFilePath());
}
/*@internal*/
getNormalizedAbsolutePath(fileName: string) {
return getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory());
}
/* @internal */
getChangedFiles_TestOnly() {
return this.changedFiles;
@ -924,6 +934,14 @@ namespace ts.server {
});
}
/*@internal*/ getScriptInfoPaths() {
const result: Path[] = [];
this.filenameToScriptInfo.forEach(info => {
result.push(info.path);
});
return result;
}
/**
* 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
@ -1365,7 +1383,7 @@ namespace ts.server {
return project;
}
}
return this.createInferredProject(/*isSingleInferredProject*/ false, projectRootPath);
return this.createInferredProject(projectRootPath, /*isSingleInferredProject*/ false, projectRootPath);
}
// we don't have an explicit root path, so we should try to find an inferred project
@ -1402,12 +1420,13 @@ namespace ts.server {
return this.inferredProjects[0];
}
return this.createInferredProject(/*isSingleInferredProject*/ true);
// Single inferred project does not have a project root.
return this.createInferredProject(/*currentDirectory*/ undefined, /*isSingleInferredProject*/ true);
}
private createInferredProject(isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject {
private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject {
const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects;
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath);
const project = new InferredProject(this, this.documentRegistry, compilerOptions, currentDirectory, projectRootPath);
if (isSingleInferredProject) {
this.inferredProjects.unshift(project);
}
@ -1419,8 +1438,8 @@ namespace ts.server {
createInferredProjectWithRootFileIfNecessary(root: ScriptInfo, projectRootPath?: string) {
const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(root, projectRootPath) ||
this.getOrCreateSingleInferredProjectIfEnabled() ||
this.createInferredProject();
this.getOrCreateSingleInferredProjectIfEnabled() ||
this.createInferredProject(getDirectoryPath(root.path));
project.addRoot(root);

View File

@ -173,7 +173,7 @@ namespace ts.server {
}
getDefaultLibFileName() {
const nodeModuleBinDir = getDirectoryPath(normalizePath(this.host.getExecutingFilePath()));
const nodeModuleBinDir = getDirectoryPath(this.project.projectService.getExecutingFilePath());
return combinePaths(nodeModuleBinDir, getDefaultLibFileName(this.compilationSettings));
}
@ -203,7 +203,7 @@ namespace ts.server {
}
getCurrentDirectory(): string {
return this.host.getCurrentDirectory();
return this.project.currentDirectory;
}
resolvePath(path: string): string {

View File

@ -177,6 +177,9 @@ namespace ts.server {
return result.module;
}
/*@internal*/
readonly currentDirectory: string;
constructor(
private readonly projectName: string,
readonly projectKind: ProjectKind,
@ -185,8 +188,9 @@ namespace ts.server {
hasExplicitListOfFiles: boolean,
languageServiceEnabled: boolean,
private compilerOptions: CompilerOptions,
public compileOnSaveEnabled: boolean) {
public compileOnSaveEnabled: boolean,
currentDirectory: string | undefined) {
this.currentDirectory = this.projectService.getNormalizedAbsolutePath(currentDirectory || "");
if (!this.compilerOptions) {
this.compilerOptions = getDefaultCompilerOptions();
this.compilerOptions.allowNonTsExtensions = true;
@ -268,7 +272,6 @@ namespace ts.server {
getProjectName() {
return this.projectName;
}
abstract getProjectRootPath(): string | undefined;
abstract getTypeAcquisition(): TypeAcquisition;
getExternalFiles(): SortedReadonlyArray<string> {
@ -363,7 +366,7 @@ namespace ts.server {
return map(this.program.getSourceFiles(), sourceFile => {
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.path);
if (!scriptInfo) {
Debug.fail(`scriptInfo for a file '${sourceFile.fileName}' is missing.`);
Debug.fail(`scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' is missing.\nProgram currentDirectory: '${this.program.getCurrentDirectory()}'\nCurrentScriptInfos: ${this.projectService.getScriptInfoPaths()}\ncurrentDirectory: ${this.projectService.host.getCurrentDirectory()}`);
}
return scriptInfo;
});
@ -842,8 +845,6 @@ namespace ts.server {
* the file and its imports/references are put into an InferredProject.
*/
export class InferredProject extends Project {
public readonly projectRootPath: string | undefined;
private static readonly newName = (() => {
let nextId = 1;
return () => {
@ -882,7 +883,7 @@ namespace ts.server {
// Used to keep track of what directories are watched for this project
directoriesWatchedForTsconfig: string[] = [];
constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, projectRootPath?: string) {
constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, currentDirectory: string | undefined, readonly projectRootPath: string | undefined) {
super(InferredProject.newName(),
ProjectKind.Inferred,
projectService,
@ -890,7 +891,8 @@ namespace ts.server {
/*files*/ undefined,
/*languageServiceEnabled*/ true,
compilerOptions,
/*compileOnSaveEnabled*/ false);
/*compileOnSaveEnabled*/ false,
currentDirectory);
this.projectRootPath = projectRootPath;
}
@ -910,15 +912,6 @@ namespace ts.server {
super.removeRoot(info);
}
getProjectRootPath() {
// Single inferred project does not have a project root.
if (this.projectService.useSingleInferredProject) {
return undefined;
}
const rootFiles = this.getRootFiles();
return getDirectoryPath(rootFiles[0]);
}
close() {
super.close();
@ -962,7 +955,15 @@ namespace ts.server {
private wildcardDirectories: Map<WatchDirectoryFlags>,
languageServiceEnabled: boolean,
public compileOnSaveEnabled: boolean) {
super(configFileName, ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled);
super(configFileName,
ProjectKind.Configured,
projectService,
documentRegistry,
hasExplicitListOfFiles,
languageServiceEnabled,
compilerOptions,
compileOnSaveEnabled,
getDirectoryPath(configFileName));
this.canonicalConfigFilePath = asNormalizedPath(projectService.toCanonicalFileName(configFileName));
this.enablePlugins();
}
@ -982,7 +983,7 @@ namespace ts.server {
// Search our peer node_modules, then any globally-specified probe paths
// ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/
const searchPaths = [combinePaths(host.getExecutingFilePath(), "../../.."), ...this.projectService.pluginProbeLocations];
const searchPaths = [combinePaths(this.projectService.getExecutingFilePath(), "../../.."), ...this.projectService.pluginProbeLocations];
if (this.projectService.allowLocalPluginLoads) {
const local = getDirectoryPath(this.canonicalConfigFilePath);
@ -1062,10 +1063,6 @@ namespace ts.server {
}
}
getProjectRootPath() {
return getDirectoryPath(this.getConfigFilePath());
}
setProjectErrors(projectErrors: ReadonlyArray<Diagnostic>) {
this.projectErrors = projectErrors;
}
@ -1196,25 +1193,22 @@ namespace ts.server {
compilerOptions: CompilerOptions,
languageServiceEnabled: boolean,
public compileOnSaveEnabled: boolean,
private readonly projectFilePath?: string) {
super(externalProjectName, ProjectKind.External, projectService, documentRegistry, /*hasExplicitListOfFiles*/ true, languageServiceEnabled, compilerOptions, compileOnSaveEnabled);
projectFilePath?: string) {
super(externalProjectName,
ProjectKind.External,
projectService,
documentRegistry,
/*hasExplicitListOfFiles*/ true,
languageServiceEnabled,
compilerOptions,
compileOnSaveEnabled,
getDirectoryPath(projectFilePath || normalizeSlashes(externalProjectName)));
}
getExcludedFiles() {
return this.excludedFiles;
}
getProjectRootPath() {
if (this.projectFilePath) {
return getDirectoryPath(this.projectFilePath);
}
// if the projectFilePath is not given, we make the assumption that the project name
// is the path of the project file. AS the project name is provided by VS, we need to
// normalize slashes before using it as a file name.
return getDirectoryPath(normalizeSlashes(this.getProjectName()));
}
getTypeAcquisition() {
return this.typeAcquisition;
}

View File

@ -14,11 +14,11 @@
////console.log("nothing");
goTo.file("a.ts")
verify.ProjectInfo(["lib.d.ts", "a.ts"])
verify.ProjectInfo(["/lib.d.ts", "a.ts"])
goTo.file("b.ts")
verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts"])
verify.ProjectInfo(["/lib.d.ts", "a.ts", "b.ts"])
goTo.file("c.ts")
verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "c.ts"])
verify.ProjectInfo(["/lib.d.ts", "a.ts", "b.ts", "c.ts"])
goTo.file("d.ts")
verify.ProjectInfo(["lib.d.ts", "d.ts"])
verify.ProjectInfo(["/lib.d.ts", "d.ts"])

View File

@ -10,4 +10,4 @@
////{ "files": ["a.ts", "b.ts"] }
goTo.file("a.ts")
verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "tsconfig.json"])
verify.ProjectInfo(["/lib.d.ts", "a.ts", "b.ts", "tsconfig.json"])

View File

@ -10,4 +10,4 @@
////{ "files": ["a.ts", "c.ts", "b.ts"] }
goTo.file("a.ts");
verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "tsconfig.json"])
verify.ProjectInfo(["/lib.d.ts", "a.ts", "b.ts", "tsconfig.json"])