mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 11:35:42 -06:00
Swap out TSD for Types 2.0
This commit is contained in:
parent
5e37a310d7
commit
1f9f20f043
@ -213,7 +213,7 @@ namespace ts.server {
|
||||
}
|
||||
switch (response.kind) {
|
||||
case "set":
|
||||
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typingOptions, response.typings, response.files);
|
||||
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typingOptions, response.typings);
|
||||
project.updateGraph();
|
||||
break;
|
||||
case "invalidate":
|
||||
|
||||
@ -355,6 +355,9 @@ namespace ts.server {
|
||||
removed.push(id);
|
||||
}
|
||||
}
|
||||
if (added.length > 0 || removed.length > 0) {
|
||||
this.projectService.typingsCache.invalidateCachedTypingsForProject(this);
|
||||
}
|
||||
this.lastReportedFileNames = currentFiles;
|
||||
|
||||
this.lastReportedFileNames = currentFiles;
|
||||
|
||||
1
src/server/types.d.ts
vendored
1
src/server/types.d.ts
vendored
@ -45,7 +45,6 @@ declare namespace ts.server {
|
||||
readonly typingOptions: ts.TypingOptions;
|
||||
readonly compilerOptions: ts.CompilerOptions;
|
||||
readonly typings: string[];
|
||||
readonly files: string[];
|
||||
readonly kind: "set";
|
||||
}
|
||||
|
||||
|
||||
@ -17,12 +17,11 @@ namespace ts.server {
|
||||
readonly typingOptions: TypingOptions;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typings: TypingsArray;
|
||||
readonly files: string[];
|
||||
poisoned: boolean;
|
||||
}
|
||||
|
||||
const emptyArray: any[] = [];
|
||||
const jsOrDts = [".js", ".d.ts"];
|
||||
const jsOrDts = [".js", ".jsx", ".d.ts"];
|
||||
|
||||
function getTypingOptionsForProjects(proj: Project): TypingOptions {
|
||||
if (proj.projectKind === ProjectKind.Configured) {
|
||||
@ -74,10 +73,6 @@ namespace ts.server {
|
||||
return opt1.allowJs != opt2.allowJs;
|
||||
}
|
||||
|
||||
function filesChanged(before: string[], after: string[]): boolean {
|
||||
return !setIsEqualTo(before, after);
|
||||
}
|
||||
|
||||
export interface TypingsArray extends ReadonlyArray<string> {
|
||||
" __typingsArrayBrand": any;
|
||||
}
|
||||
@ -102,18 +97,17 @@ namespace ts.server {
|
||||
|
||||
const entry = this.perProjectCache[project.getProjectName()];
|
||||
const result: TypingsArray = entry ? entry.typings : <any>emptyArray;
|
||||
if (!entry || typingOptionsChanged(typingOptions, entry.typingOptions) || compilerOptionsChanged(project.getCompilerOptions(), entry.compilerOptions) || filesChanged(project.getFileNames(), entry.files)) {
|
||||
// something has been changed, issue a request to update typings
|
||||
this.installer.enqueueInstallTypingsRequest(project, typingOptions);
|
||||
if (!entry || typingOptionsChanged(typingOptions, entry.typingOptions) || compilerOptionsChanged(project.getCompilerOptions(), entry.compilerOptions)) {
|
||||
// Note: entry is now poisoned since it does not really contain typings for a given combination of compiler options\typings options.
|
||||
// instead it acts as a placeholder to prevent issuing multiple requests
|
||||
this.perProjectCache[project.getProjectName()] = {
|
||||
compilerOptions: project.getCompilerOptions(),
|
||||
typingOptions,
|
||||
typings: result,
|
||||
files: project.getFileNames(),
|
||||
poisoned: true
|
||||
};
|
||||
// something has been changed, issue a request to update typings
|
||||
this.installer.enqueueInstallTypingsRequest(project, typingOptions);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -126,12 +120,11 @@ namespace ts.server {
|
||||
this.installer.enqueueInstallTypingsRequest(project, typingOptions);
|
||||
}
|
||||
|
||||
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typingOptions: TypingOptions, newTypings: string[], files: string[]) {
|
||||
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typingOptions: TypingOptions, newTypings: string[]) {
|
||||
this.perProjectCache[projectName] = {
|
||||
compilerOptions,
|
||||
typingOptions,
|
||||
typings: toTypingsArray(newTypings),
|
||||
files: files,
|
||||
poisoned: false
|
||||
};
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ namespace ts.server.typingsInstaller {
|
||||
private exec: { (command: string, options: { cwd: string }, callback?: (error: Error, stdout: string, stderr: string) => void): any };
|
||||
private npmBinPath: string;
|
||||
|
||||
private tsdRunCount = 1;
|
||||
private installRunCount = 1;
|
||||
readonly installTypingHost: InstallTypingHost = sys;
|
||||
|
||||
constructor(log?: Log) {
|
||||
@ -101,23 +101,6 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
protected installPackage(packageName: string) {
|
||||
try {
|
||||
const output = this.execSync(`npm install --silent --global ${packageName}`, { stdio: "pipe" }).toString();
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`installPackage::stdout '${output}'`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`installPackage::err::stdout '${e.stdout && e.stdout.toString()}'`);
|
||||
this.log.writeLine(`installPackage::err::stderr '${e.stdout && e.stderr.toString()}'`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected sendResponse(response: SetTypings | InvalidateCachedTypings) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Sending response: ${JSON.stringify(response)}`);
|
||||
@ -128,30 +111,23 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
protected runTsd(cachePath: string, typingsToInstall: string[], postInstallAction: (installedTypings: string[]) => void): void {
|
||||
const id = this.tsdRunCount;
|
||||
this.tsdRunCount++;
|
||||
const tsdPath = combinePaths(this.npmBinPath, "tsd");
|
||||
const command = `${tsdPath} install ${typingsToInstall.join(" ")} -ros`;
|
||||
protected runInstall(cachePath: string, typingsToInstall: string[], postInstallAction: (installedTypings: string[]) => void): void {
|
||||
const id = this.installRunCount;
|
||||
this.installRunCount++;
|
||||
const command = `npm install @types/${typingsToInstall.join(" @types/")} --save-dev`;
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Running tsd ${id}, command '${command}'. cache path '${cachePath}'`);
|
||||
this.log.writeLine(`Running npm install @types ${id}, command '${command}'. cache path '${cachePath}'`);
|
||||
}
|
||||
this.exec(command, { cwd: cachePath }, (err, stdout, stderr) => {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`TSD ${id} stdout: ${stdout}`);
|
||||
this.log.writeLine(`TSD ${id} stderr: ${stderr}`);
|
||||
}
|
||||
const i = stdout.indexOf("running install");
|
||||
if (i < 0) {
|
||||
return;
|
||||
this.log.writeLine(`npm install @types ${id} stdout: ${stdout}`);
|
||||
this.log.writeLine(`npm install @types ${id} stderr: ${stderr}`);
|
||||
}
|
||||
const installedTypings: string[] = [];
|
||||
|
||||
const expr = /^\s*-\s*(\S+)\s*$/gm;
|
||||
expr.lastIndex = i;
|
||||
const expr = /^.*(node_modules)\\(@types)\\(\S+)\s*$/gm;
|
||||
let match: RegExpExecArray;
|
||||
while (match = expr.exec(stdout)) {
|
||||
installedTypings.push(match[1]);
|
||||
installedTypings.push(`${match[1]}/${match[2]}/${match[3]}`);
|
||||
}
|
||||
postInstallAction(installedTypings);
|
||||
});
|
||||
|
||||
@ -1,16 +1,10 @@
|
||||
/// <reference path="../../compiler/core.ts" />
|
||||
/// <reference path="../../services/jsTyping.ts"/>
|
||||
/// <reference path="../types.d.ts"/>
|
||||
|
||||
namespace ts.server.typingsInstaller {
|
||||
const DefaultTsdSettings = JSON.stringify({
|
||||
version: "v4",
|
||||
repo: "DefinitelyTyped/DefinitelyTyped",
|
||||
ref: "master",
|
||||
path: "typings"
|
||||
}, /*replacer*/undefined, /*space*/4);
|
||||
|
||||
interface TsdConfig {
|
||||
installed: MapLike<any>;
|
||||
interface NpmConfig {
|
||||
devDependencies: MapLike<any>;
|
||||
}
|
||||
|
||||
export interface Log {
|
||||
@ -23,18 +17,17 @@ namespace ts.server.typingsInstaller {
|
||||
writeLine: () => {}
|
||||
};
|
||||
|
||||
function tsdTypingToFileName(cachePath: string, tsdTypingFile: string) {
|
||||
return combinePaths(cachePath, `typings/${tsdTypingFile}`);
|
||||
function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost): string {
|
||||
const result = resolveModuleName(packageName, combinePaths(cachePath, "index.d.ts"), { moduleResolution: ModuleResolutionKind.NodeJs }, installTypingHost);
|
||||
return result.resolvedModule ? result.resolvedModule.resolvedFileName : null;
|
||||
}
|
||||
|
||||
function getPackageName(tsdTypingFile: string) {
|
||||
const idx = tsdTypingFile.indexOf("/");
|
||||
return idx > 0 ? tsdTypingFile.substr(0, idx) : undefined;
|
||||
function getPackageName(typingFile: string) {
|
||||
const idx = typingFile.lastIndexOf("/");
|
||||
return idx > 0 ? typingFile.substr(idx + 1) : undefined;
|
||||
}
|
||||
|
||||
export abstract class TypingsInstaller {
|
||||
private isTsdInstalled: boolean;
|
||||
|
||||
private packageNameToTypingLocation: Map<string> = createMap<string>();
|
||||
private missingTypingsSet: Map<true> = createMap<true>();
|
||||
private knownCachesSet: Map<true> = createMap<true>();
|
||||
@ -50,20 +43,6 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
|
||||
init() {
|
||||
this.isTsdInstalled = this.isPackageInstalled("tsd");
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`isTsdInstalled: ${this.isTsdInstalled}`);
|
||||
}
|
||||
|
||||
if (!this.isTsdInstalled) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`tsd is not installed, installing tsd...`);
|
||||
}
|
||||
this.isTsdInstalled = this.installPackage("tsd");
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`isTsdInstalled: ${this.isTsdInstalled}`);
|
||||
}
|
||||
}
|
||||
this.processCacheLocation(this.globalCachePath);
|
||||
}
|
||||
|
||||
@ -94,13 +73,6 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
|
||||
install(req: DiscoverTypings) {
|
||||
if (!this.isTsdInstalled) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`tsd is not installed, ignoring request...`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Got install request ${JSON.stringify(req)}`);
|
||||
}
|
||||
@ -153,23 +125,26 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
return;
|
||||
}
|
||||
const tsdJson = combinePaths(cacheLocation, "tsd.json");
|
||||
const packageJson = combinePaths(cacheLocation, "package.json");
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Trying to find '${tsdJson}'...`);
|
||||
this.log.writeLine(`Trying to find '${packageJson}'...`);
|
||||
}
|
||||
if (this.installTypingHost.fileExists(tsdJson)) {
|
||||
const tsdConfig = <TsdConfig>JSON.parse(this.installTypingHost.readFile(tsdJson));
|
||||
if (this.installTypingHost.fileExists(packageJson)) {
|
||||
const npmConfig = <NpmConfig>JSON.parse(this.installTypingHost.readFile(packageJson));
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Loaded content of '${tsdJson}': ${JSON.stringify(tsdConfig)}`);
|
||||
this.log.writeLine(`Loaded content of '${npmConfig}': ${JSON.stringify(npmConfig)}`);
|
||||
}
|
||||
if (tsdConfig.installed) {
|
||||
for (const key in tsdConfig.installed) {
|
||||
// key is <package name>/<typing file>
|
||||
if (npmConfig.devDependencies) {
|
||||
for (const key in npmConfig.devDependencies) {
|
||||
// key is @types/<package name>
|
||||
const packageName = getPackageName(key);
|
||||
if (!packageName) {
|
||||
continue;
|
||||
}
|
||||
const typingFile = tsdTypingToFileName(cacheLocation, key);
|
||||
var typingFile = typingToFileName(cacheLocation, packageName, this.installTypingHost);
|
||||
if (!typingFile) {
|
||||
continue;
|
||||
}
|
||||
const existingTypingFile = this.packageNameToTypingLocation[packageName];
|
||||
if (existingTypingFile === typingFile) {
|
||||
continue;
|
||||
@ -204,20 +179,19 @@ namespace ts.server.typingsInstaller {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: install typings and send response when they are ready
|
||||
const tsdPath = combinePaths(cachePath, "tsd.json");
|
||||
const npmConfigPath = combinePaths(cachePath, "package.json");
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Tsd config file: ${tsdPath}`);
|
||||
this.log.writeLine(`Npm config file: ${npmConfigPath}`);
|
||||
}
|
||||
if (!this.installTypingHost.fileExists(tsdPath)) {
|
||||
if (!this.installTypingHost.fileExists(npmConfigPath)) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Tsd config file '${tsdPath}' is missing, creating new one...`);
|
||||
this.log.writeLine(`Npm config file: '${npmConfigPath}' is missing, creating new one...`);
|
||||
}
|
||||
this.ensureDirectoryExists(cachePath, this.installTypingHost);
|
||||
this.installTypingHost.writeFile(tsdPath, DefaultTsdSettings);
|
||||
this.installTypingHost.writeFile(npmConfigPath, "{}");
|
||||
}
|
||||
|
||||
this.runTsd(cachePath, typingsToInstall, installedTypings => {
|
||||
this.runInstall(cachePath, typingsToInstall, installedTypings => {
|
||||
// TODO: watch project directory
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Requested to install typings ${JSON.stringify(typingsToInstall)}, installed typings ${JSON.stringify(installedTypings)}`);
|
||||
@ -230,7 +204,11 @@ namespace ts.server.typingsInstaller {
|
||||
continue;
|
||||
}
|
||||
installedPackages[packageName] = true;
|
||||
installedTypingFiles.push(tsdTypingToFileName(cachePath, t));
|
||||
var typingFile = typingToFileName(cachePath, packageName, this.installTypingHost);
|
||||
if (!typingFile) {
|
||||
continue;
|
||||
}
|
||||
installedTypingFiles.push(typingFile);
|
||||
}
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Installed typing files ${JSON.stringify(installedTypingFiles)}`);
|
||||
@ -287,14 +265,12 @@ namespace ts.server.typingsInstaller {
|
||||
typingOptions: request.typingOptions,
|
||||
compilerOptions: request.compilerOptions,
|
||||
typings,
|
||||
files: request.fileNames,
|
||||
kind: "set"
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract isPackageInstalled(packageName: string): boolean;
|
||||
protected abstract installPackage(packageName: string): boolean;
|
||||
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings): void;
|
||||
protected abstract runTsd(cachePath: string, typingsToInstall: string[], postInstallAction: (installedTypings: string[]) => void): void;
|
||||
protected abstract runInstall(cachePath: string, typingsToInstall: string[], postInstallAction: (installedTypings: string[]) => void): void;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user