mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-20 22:51:17 -05:00
add tsserver specific resolution pass that will load typings from cache locations if auto discovery is enabled
This commit is contained in:
@@ -1571,7 +1571,8 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function createResolvedModule(resolvedFileName: string, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
|
||||
/* @internal */
|
||||
export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
|
||||
return { resolvedModule: resolvedFileName ? { resolvedFileName, isExternalLibraryImport } : undefined, failedLookupLocations };
|
||||
}
|
||||
|
||||
@@ -1989,7 +1990,7 @@ namespace ts {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder, moduleName);
|
||||
}
|
||||
resolvedFileName = loadModuleFromNodeModules(moduleName, containingDirectory, failedLookupLocations, state);
|
||||
resolvedFileName = loadModuleFromNodeModules(moduleName, containingDirectory, failedLookupLocations, state, /*checkOneLevel*/ false);
|
||||
isExternalLibraryImport = resolvedFileName !== undefined;
|
||||
}
|
||||
else {
|
||||
@@ -2138,7 +2139,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
|
||||
export function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): string {
|
||||
directory = normalizeSlashes(directory);
|
||||
while (true) {
|
||||
const baseName = getBaseFileName(directory);
|
||||
@@ -2159,7 +2160,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const parentPath = getDirectoryPath(directory);
|
||||
if (parentPath === directory) {
|
||||
if (parentPath === directory || checkOneLevel) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -2840,6 +2840,10 @@
|
||||
"category": "Error",
|
||||
"code": 6138
|
||||
},
|
||||
"Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 6139
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace ts {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
|
||||
}
|
||||
resolvedFile = loadModuleFromNodeModules(typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState);
|
||||
resolvedFile = loadModuleFromNodeModules(typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*checkOneLevel*/ false);
|
||||
if (traceEnabled) {
|
||||
if (resolvedFile) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, false);
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace ts {
|
||||
|
||||
class TestTypingsInstaller extends server.typingsInstaller.TypingsInstaller implements server.ITypingsInstaller {
|
||||
protected projectService: server.ProjectService;
|
||||
constructor(readonly cachePath: string, readonly installTypingHost: server.ServerHost) {
|
||||
super(cachePath, <Path>"");
|
||||
constructor(readonly globalTypingsCacheLocation: string, readonly installTypingHost: server.ServerHost) {
|
||||
super(globalTypingsCacheLocation, <Path>"");
|
||||
this.init();
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
|
||||
const request = server.createInstallTypingsRequest(project, typingOptions, this.cachePath);
|
||||
const request = server.createInstallTypingsRequest(project, typingOptions, this.globalTypingsCacheLocation);
|
||||
this.install(request);
|
||||
}
|
||||
}
|
||||
@@ -2030,7 +2030,7 @@ namespace ts {
|
||||
const p = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(p, [file1.path]);
|
||||
|
||||
assert(host.fileExists(combinePaths(installer.cachePath, "tsd.json")));
|
||||
assert(host.fileExists(combinePaths(installer.globalTypingsCacheLocation, "tsd.json")));
|
||||
|
||||
installer.runPostInstallActions(t => {
|
||||
assert.deepEqual(t, ["jquery"]);
|
||||
@@ -2070,7 +2070,7 @@ namespace ts {
|
||||
const p = projectService.inferredProjects[0];
|
||||
checkProjectActualFiles(p, [file1.path]);
|
||||
|
||||
assert(host.fileExists(combinePaths(installer.cachePath, "tsd.json")));
|
||||
assert(host.fileExists(combinePaths(installer.globalTypingsCacheLocation, "tsd.json")));
|
||||
|
||||
installer.runPostInstallActions(t => {
|
||||
assert.deepEqual(t, ["jquery"]);
|
||||
@@ -2398,4 +2398,121 @@ namespace ts {
|
||||
assert.isTrue(typingOptions.enableAutoDiscovery, "Typing autodiscovery should be enabled");
|
||||
});
|
||||
});
|
||||
|
||||
describe("extra resolution pass in lshost", () => {
|
||||
it("can load typings that are proper modules", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/app.js",
|
||||
content: `var x = require("lib")`
|
||||
};
|
||||
const lib = {
|
||||
path: "/a/cache/node_modules/@types/lib/index.d.ts",
|
||||
content: "export let x = 1"
|
||||
};
|
||||
const host: TestServerHost & ModuleResolutionHost = createServerHost([file1, lib]);
|
||||
const resolutionTrace: string[] = [];
|
||||
host.trace = resolutionTrace.push.bind(resolutionTrace);
|
||||
const projectService = createProjectService(host, { typingsInstaller: new TestTypingsInstaller("/a/cache", host) });
|
||||
|
||||
projectService.setCompilerOptionsForInferredProjects({ traceResolution: true, allowJs: true });
|
||||
projectService.openClientFile(file1.path);
|
||||
projectService.checkNumberOfProjects({ inferredProjects: 1 });
|
||||
const proj = projectService.inferredProjects[0];
|
||||
|
||||
assert.deepEqual(resolutionTrace, [
|
||||
"======== Resolving module 'lib' from '/a/b/app.js'. ========",
|
||||
"Module resolution kind is not specified, using 'NodeJs'.",
|
||||
"Loading module 'lib' from 'node_modules' folder.",
|
||||
"File '/a/b/node_modules/lib.ts' does not exist.",
|
||||
"File '/a/b/node_modules/lib.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/lib.js' does not exist.",
|
||||
"File '/a/b/node_modules/lib.jsx' does not exist.",
|
||||
"File '/a/b/node_modules/lib/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.ts' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.js' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.js' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.jsx' does not exist.",
|
||||
"File '/a/node_modules/lib.ts' does not exist.",
|
||||
"File '/a/node_modules/lib.tsx' does not exist.",
|
||||
"File '/a/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/a/node_modules/lib.js' does not exist.",
|
||||
"File '/a/node_modules/lib.jsx' does not exist.",
|
||||
"File '/a/node_modules/lib/package.json' does not exist.",
|
||||
"File '/a/node_modules/lib/index.ts' does not exist.",
|
||||
"File '/a/node_modules/lib/index.tsx' does not exist.",
|
||||
"File '/a/node_modules/lib/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/lib/index.js' does not exist.",
|
||||
"File '/a/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.tsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.tsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.js' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.jsx' does not exist.",
|
||||
"File '/node_modules/lib.ts' does not exist.",
|
||||
"File '/node_modules/lib.tsx' does not exist.",
|
||||
"File '/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/node_modules/lib.js' does not exist.",
|
||||
"File '/node_modules/lib.jsx' does not exist.",
|
||||
"File '/node_modules/lib/package.json' does not exist.",
|
||||
"File '/node_modules/lib/index.ts' does not exist.",
|
||||
"File '/node_modules/lib/index.tsx' does not exist.",
|
||||
"File '/node_modules/lib/index.d.ts' does not exist.",
|
||||
"File '/node_modules/lib/index.js' does not exist.",
|
||||
"File '/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/node_modules/@types/lib.ts' does not exist.",
|
||||
"File '/node_modules/@types/lib.tsx' does not exist.",
|
||||
"File '/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.ts' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.tsx' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.js' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.jsx' does not exist.",
|
||||
"======== Module name 'lib' was not resolved. ========",
|
||||
`Auto discovery for typings is enabled in project '${proj.getProjectName()}'. Running extra resolution pass for module 'lib' using cache location '/a/cache'.`,
|
||||
"File '/a/cache/node_modules/lib.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/lib.tsx' does not exist.",
|
||||
"File '/a/cache/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/lib.js' does not exist.",
|
||||
"File '/a/cache/node_modules/lib.jsx' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/package.json' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.tsx' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.js' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.tsx' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/index.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/index.tsx' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/index.d.ts' exist - use it as a name resolution result.",
|
||||
]);
|
||||
checkProjectActualFiles(proj, [ file1.path, lib.path ]);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -183,17 +183,16 @@ namespace ts.server {
|
||||
public readonly logger: Logger,
|
||||
public readonly cancellationToken: HostCancellationToken,
|
||||
private readonly useSingleInferredProject: boolean,
|
||||
private typingsInstaller: ITypingsInstaller,
|
||||
readonly typingsInstaller: ITypingsInstaller = nullTypingsInstaller,
|
||||
private readonly eventHandler?: ProjectServiceEventHandler) {
|
||||
|
||||
this.toCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
this.directoryWatchers = new DirectoryWatchers(this);
|
||||
this.throttledOperations = new ThrottledOperations(host);
|
||||
|
||||
const installer = typingsInstaller || nullTypingsInstaller;
|
||||
installer.attach(this);
|
||||
this.typingsInstaller.attach(this);
|
||||
|
||||
this.typingsCache = new TypingsCache(installer);
|
||||
this.typingsCache = new TypingsCache(this.typingsInstaller);
|
||||
|
||||
// ts.disableIncrementalParsing = true;
|
||||
|
||||
|
||||
@@ -9,10 +9,37 @@ namespace ts.server {
|
||||
private readonly resolvedTypeReferenceDirectives: ts.FileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>;
|
||||
private readonly getCanonicalFileName: (fileName: string) => string;
|
||||
|
||||
private readonly resolveModuleName: typeof resolveModuleName;
|
||||
readonly trace: (s: string) => void;
|
||||
|
||||
constructor(private readonly host: ServerHost, private readonly project: Project, private readonly cancellationToken: HostCancellationToken) {
|
||||
this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
|
||||
this.resolvedModuleNames = createFileMap<Map<ResolvedModuleWithFailedLookupLocations>>();
|
||||
this.resolvedTypeReferenceDirectives = createFileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
|
||||
if (host.trace) {
|
||||
this.trace = s => host.trace(s);
|
||||
}
|
||||
|
||||
this.resolveModuleName = (moduleName, containingFile, compilerOptions, host) => {
|
||||
const primaryResult = resolveModuleName(moduleName, containingFile, compilerOptions, host);
|
||||
if (primaryResult.resolvedModule) {
|
||||
return primaryResult;
|
||||
}
|
||||
const globalCache = this.project.projectService.typingsInstaller.globalTypingsCacheLocation;
|
||||
if (this.project.getTypingOptions().enableAutoDiscovery && globalCache) {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, this.project.getProjectName(), moduleName, globalCache);
|
||||
}
|
||||
const state: ModuleResolutionState = { compilerOptions, host, skipTsx: false, traceEnabled };
|
||||
const resolvedName = loadModuleFromNodeModules(moduleName, globalCache, primaryResult.failedLookupLocations, state, /*checkOneLevel*/ true);
|
||||
if (resolvedName) {
|
||||
return createResolvedModule(resolvedName, /*isExternalLibraryImport*/ true, primaryResult.failedLookupLocations);
|
||||
}
|
||||
}
|
||||
return primaryResult;
|
||||
};
|
||||
}
|
||||
|
||||
private resolveNamesWithLocalCache<T extends { failedLookupLocations: string[] }, R>(
|
||||
@@ -89,7 +116,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string): ResolvedModule[] {
|
||||
return this.resolveNamesWithLocalCache(moduleNames, containingFile, this.resolvedModuleNames, resolveModuleName, m => m.resolvedModule);
|
||||
return this.resolveNamesWithLocalCache(moduleNames, containingFile, this.resolvedModuleNames, this.resolveModuleName, m => m.resolvedModule);
|
||||
}
|
||||
|
||||
getDefaultLibFileName() {
|
||||
|
||||
@@ -13,6 +13,29 @@ namespace ts.server {
|
||||
fork(modulePath: string, args: string[], options?: { execArgv: string[], env?: MapLike<string> }): NodeChildProcess;
|
||||
} = require("child_process");
|
||||
|
||||
const os: {
|
||||
homedir(): string
|
||||
} = require("os");
|
||||
|
||||
|
||||
function getGlobalTypingsCacheLocation() {
|
||||
let basePath: string;
|
||||
switch (process.platform) {
|
||||
case "win32":
|
||||
basePath = process.env.LOCALAPPDATA || process.env.APPDATA || os.homedir();
|
||||
break;
|
||||
case "linux":
|
||||
basePath = os.homedir();
|
||||
break;
|
||||
case "darwin":
|
||||
basePath = combinePaths(os.homedir(), "Library/Application Support/");
|
||||
break;
|
||||
}
|
||||
|
||||
Debug.assert(basePath !== undefined);
|
||||
return combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript");
|
||||
}
|
||||
|
||||
interface NodeChildProcess {
|
||||
send(message: any, sendHandle?: any): void;
|
||||
on(message: "message", f: (m: any) => void): void;
|
||||
@@ -167,7 +190,11 @@ namespace ts.server {
|
||||
private socket: NodeSocket;
|
||||
private projectService: ProjectService;
|
||||
|
||||
constructor(private readonly logger: server.Logger, private readonly eventPort: number, private newLine: string) {
|
||||
constructor(
|
||||
private readonly logger: server.Logger,
|
||||
private readonly eventPort: number,
|
||||
readonly globalTypingsCacheLocation: string,
|
||||
private newLine: string) {
|
||||
if (eventPort) {
|
||||
const s = net.connect({ port: eventPort }, () => {
|
||||
this.socket = s;
|
||||
@@ -181,7 +208,7 @@ namespace ts.server {
|
||||
this.logger.info("Binding...");
|
||||
}
|
||||
|
||||
const args: string[] = [];
|
||||
const args: string[] = ["--globalTypingsCacheLocation", this.globalTypingsCacheLocation];
|
||||
if (this.logger.loggingEnabled() && this.logger.getLogFileName()) {
|
||||
args.push("--logFile", combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName())), `ti-${process.pid}.log`));
|
||||
}
|
||||
@@ -238,12 +265,13 @@ namespace ts.server {
|
||||
installerEventPort: number,
|
||||
canUseEvents: boolean,
|
||||
useSingleInferredProject: boolean,
|
||||
globalTypingsCacheLocation: string,
|
||||
logger: server.Logger) {
|
||||
super(
|
||||
host,
|
||||
cancellationToken,
|
||||
useSingleInferredProject,
|
||||
new NodeTypingsInstaller(logger, installerEventPort, host.newLine),
|
||||
new NodeTypingsInstaller(logger, installerEventPort, globalTypingsCacheLocation, host.newLine),
|
||||
Buffer.byteLength,
|
||||
process.hrtime,
|
||||
logger,
|
||||
@@ -442,12 +470,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
function writeCompressedData(prefix: string, compressed: CompressedData, suffix: string): void {
|
||||
sys.write(prefix);
|
||||
writeMessage(compressed.data);
|
||||
sys.write(suffix);
|
||||
}
|
||||
|
||||
const sys = <ServerHost>ts.sys;
|
||||
|
||||
// Override sys.write because fs.writeSync is not reliable on Node 4
|
||||
@@ -463,7 +485,6 @@ namespace ts.server {
|
||||
sys.clearTimeout = clearTimeout;
|
||||
sys.setImmediate = setImmediate;
|
||||
sys.clearImmediate = clearImmediate;
|
||||
sys.writeCompressedData = writeCompressedData;
|
||||
if (typeof global !== "undefined" && global.gc) {
|
||||
sys.gc = () => global.gc();
|
||||
}
|
||||
@@ -491,7 +512,14 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
const useSingleInferredProject = sys.args.indexOf("--useSingleInferredProject") >= 0;
|
||||
const ioSession = new IOSession(sys, cancellationToken, eventPort, /*canUseEvents*/ eventPort === undefined, useSingleInferredProject, logger);
|
||||
const ioSession = new IOSession(
|
||||
sys,
|
||||
cancellationToken,
|
||||
eventPort,
|
||||
/*canUseEvents*/ eventPort === undefined,
|
||||
useSingleInferredProject,
|
||||
getGlobalTypingsCacheLocation(),
|
||||
logger);
|
||||
process.on("uncaughtException", function (err: Error) {
|
||||
ioSession.logError(err, "unknown");
|
||||
});
|
||||
|
||||
1
src/server/types.d.ts
vendored
1
src/server/types.d.ts
vendored
@@ -16,6 +16,7 @@ declare namespace ts.server {
|
||||
clearImmediate(timeoutId: any): void;
|
||||
writeCompressedData(prefix: string, data: CompressedData, suffix: string): void;
|
||||
gc?(): void;
|
||||
trace?(s: string): void;
|
||||
}
|
||||
|
||||
export interface TypingInstallerRequest {
|
||||
|
||||
@@ -5,12 +5,14 @@ namespace ts.server {
|
||||
enqueueInstallTypingsRequest(p: Project, typingOptions: TypingOptions): void;
|
||||
attach(projectService: ProjectService): void;
|
||||
onProjectClosed(p: Project): void;
|
||||
readonly globalTypingsCacheLocation: string;
|
||||
}
|
||||
|
||||
export const nullTypingsInstaller: ITypingsInstaller = {
|
||||
enqueueInstallTypingsRequest: () => {},
|
||||
attach: (projectService: ProjectService) => {},
|
||||
onProjectClosed: (p: Project) => {}
|
||||
onProjectClosed: (p: Project) => {},
|
||||
globalTypingsCacheLocation: undefined
|
||||
};
|
||||
|
||||
class TypingsCacheEntry {
|
||||
|
||||
@@ -3,32 +3,10 @@
|
||||
|
||||
namespace ts.server.typingsInstaller {
|
||||
|
||||
const os: {
|
||||
homedir(): string
|
||||
} = require("os");
|
||||
|
||||
const fs: {
|
||||
appendFileSync(file: string, content: string): void
|
||||
} = require("fs");
|
||||
|
||||
function getGlobalCacheLocation() {
|
||||
let basePath: string;
|
||||
switch (process.platform) {
|
||||
case "win32":
|
||||
basePath = process.env.LOCALAPPDATA || process.env.APPDATA || os.homedir();
|
||||
break;
|
||||
case "linux":
|
||||
basePath = os.homedir();
|
||||
break;
|
||||
case "darwin":
|
||||
basePath = combinePaths(os.homedir(), "Library/Application Support/");
|
||||
break;
|
||||
}
|
||||
|
||||
Debug.assert(basePath !== undefined);
|
||||
return combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript");
|
||||
}
|
||||
|
||||
class FileLog implements Log {
|
||||
constructor(private readonly logFile?: string) {
|
||||
}
|
||||
@@ -49,8 +27,8 @@ namespace ts.server.typingsInstaller {
|
||||
private tsdRunCount = 1;
|
||||
readonly installTypingHost: InstallTypingHost = sys;
|
||||
|
||||
constructor(log?: Log) {
|
||||
super(getGlobalCacheLocation(), toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)), log);
|
||||
constructor(globalTypingsCacheLocation: string, log: Log) {
|
||||
super(globalTypingsCacheLocation, toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)), log);
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Process id: ${process.pid}`);
|
||||
}
|
||||
@@ -158,23 +136,27 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
let logFilePath: string;
|
||||
{
|
||||
const logFileIndex = sys.args.indexOf("--logFile");
|
||||
if (logFileIndex >= 0 && logFileIndex < sys.args.length - 1) {
|
||||
logFilePath = sys.args[logFileIndex + 1];
|
||||
}
|
||||
function findArgument(argumentName: string) {
|
||||
const index = sys.args.indexOf(argumentName);
|
||||
return index >= 0 && index < sys.args.length - 1
|
||||
? sys.args[index]
|
||||
: undefined;
|
||||
}
|
||||
|
||||
const logFilePath = findArgument("--logFile");
|
||||
const globalTypingsCacheLocation = findArgument("--globalTypingsCacheLocation");
|
||||
const log = new FileLog(logFilePath);
|
||||
if (log.isEnabled()) {
|
||||
process.on("uncaughtException", (e: Error) => {
|
||||
log.writeLine(`Unhandled exception: ${e} at ${e.stack}`);
|
||||
});
|
||||
process.on("disconnect", () => {
|
||||
log.writeLine(`Parent process has exited, shutting down...`);
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
const installer = new NodeTypingsInstaller(log);
|
||||
process.on("disconnect", () => {
|
||||
if (log.isEnabled()) {
|
||||
log.writeLine(`Parent process has exited, shutting down...`);
|
||||
}
|
||||
process.exit(0);
|
||||
});
|
||||
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, log);
|
||||
installer.init();
|
||||
}
|
||||
Reference in New Issue
Block a user