rust/editors/code/src/dependencies_provider.ts

136 lines
4.9 KiB
TypeScript
Raw Normal View History

2022-07-17 10:38:56 -05:00
import * as vscode from "vscode";
import * as fspath from "path";
import * as fs from "fs";
2023-04-02 19:58:20 -05:00
import { CtxInit } from "./ctx";
2022-07-17 11:05:55 -05:00
import * as ra from "./lsp_ext";
2023-04-04 11:47:01 -05:00
import { FetchDependencyListResult } from "./lsp_ext";
2022-07-17 11:05:55 -05:00
import { Ctx } from "./ctx";
import { setFlagsFromString } from "v8";
import * as ra from "./lsp_ext";
2022-02-25 18:37:55 -06:00
2022-02-25 19:37:09 -06:00
2022-07-17 10:38:56 -05:00
export class RustDependenciesProvider
implements vscode.TreeDataProvider<Dependency | DependencyFile>
{
2023-04-02 20:37:07 -05:00
dependenciesMap: { [id: string]: Dependency | DependencyFile };
ctx: CtxInit;
2022-02-25 19:37:09 -06:00
2022-07-17 11:05:55 -05:00
constructor(private readonly workspaceRoot: string,ctx: CtxInit) {
this.dependenciesMap = {};
2022-07-17 11:05:55 -05:00
this.ctx = ctx;
2022-02-25 19:37:09 -06:00
}
2022-07-17 10:38:56 -05:00
private _onDidChangeTreeData: vscode.EventEmitter<
Dependency | DependencyFile | undefined | null | void
> = new vscode.EventEmitter<Dependency | undefined | null | void>();
2022-02-25 19:37:09 -06:00
2022-07-17 10:38:56 -05:00
readonly onDidChangeTreeData: vscode.Event<
Dependency | DependencyFile | undefined | null | void
> = this._onDidChangeTreeData.event;
2022-02-25 19:37:09 -06:00
getDependency(filePath: string): Dependency | DependencyFile | undefined {
return this.dependenciesMap[filePath.toLowerCase()];
}
contains(filePath: string): boolean {
return filePath.toLowerCase() in this.dependenciesMap;
}
refresh(): void {
this._onDidChangeTreeData.fire();
}
2022-07-17 10:38:56 -05:00
getParent?(
element: Dependency | DependencyFile
): vscode.ProviderResult<Dependency | DependencyFile> {
2022-02-25 19:37:09 -06:00
if (element instanceof Dependency) return undefined;
return element.parent;
}
getTreeItem(element: Dependency | DependencyFile): vscode.TreeItem | Thenable<vscode.TreeItem> {
if (element.id! in this.dependenciesMap) return this.dependenciesMap[element.id!];
return element;
}
2022-07-17 10:38:56 -05:00
getChildren(
element?: Dependency | DependencyFile
): vscode.ProviderResult<Dependency[] | DependencyFile[]> {
2022-02-25 19:37:09 -06:00
return new Promise((resolve, _reject) => {
if (!this.workspaceRoot) {
2022-07-17 10:38:56 -05:00
void vscode.window.showInformationMessage("No dependency in empty workspace");
2022-02-25 19:37:09 -06:00
return Promise.resolve([]);
}
2022-02-25 19:37:09 -06:00
2022-02-25 19:37:09 -06:00
if (element) {
2022-07-17 10:38:56 -05:00
const files = fs.readdirSync(element.dependencyPath).map((fileName) => {
2022-02-25 19:37:09 -06:00
const filePath = fspath.join(element.dependencyPath, fileName);
2022-07-17 10:38:56 -05:00
const collapsibleState = fs.lstatSync(filePath).isDirectory()
? vscode.TreeItemCollapsibleState.Collapsed
2022-07-17 10:38:56 -05:00
: vscode.TreeItemCollapsibleState.None;
const dep = new DependencyFile(fileName, filePath, element, collapsibleState);
2022-02-25 19:37:09 -06:00
this.dependenciesMap[dep.dependencyPath.toLowerCase()] = dep;
return dep;
});
2022-07-17 10:38:56 -05:00
return resolve(files);
2022-02-25 19:37:09 -06:00
} else {
return resolve(this.getRootDependencies());
}
2022-02-25 18:37:55 -06:00
});
2022-02-25 19:37:09 -06:00
}
private async getRootDependencies(): Promise<Dependency[]> {
2022-07-17 11:05:55 -05:00
const crates = await this.ctx.client.sendRequest(ra.fetchDependencyGraph, {});
2023-04-04 11:47:01 -05:00
const dependenciesResult: FetchDependencyListResult = await this.ctx.client.sendRequest(
ra.fetchDependencyList,
2023-04-02 20:37:07 -05:00
{}
);
2023-04-02 19:58:20 -05:00
const crates = dependenciesResult.crates;
2022-07-17 10:38:56 -05:00
const deps = crates.map((crate) => {
2022-02-25 19:37:09 -06:00
const dep = this.toDep(crate.name, crate.version, crate.path);
2022-02-25 19:37:09 -06:00
this.dependenciesMap[dep.dependencyPath.toLowerCase()] = dep;
2022-02-25 19:37:09 -06:00
this.dependenciesMap[stdlib.dependencyPath.toLowerCase()] = stdlib;
return dep;
2022-02-25 19:37:09 -06:00
});
return deps;
}
2023-04-02 19:58:20 -05:00
2023-04-02 20:37:07 -05:00
private toDep(moduleName: string, version: string, path: string): Dependency {
return new Dependency(moduleName, version, path, vscode.TreeItemCollapsibleState.Collapsed);
}
2022-02-25 18:37:55 -06:00
}
export class Dependency extends vscode.TreeItem {
2022-02-25 19:37:09 -06:00
constructor(
public readonly label: string,
private version: string,
readonly dependencyPath: string,
public readonly collapsibleState: vscode.TreeItemCollapsibleState
) {
super(label, collapsibleState);
this.tooltip = `${this.label}-${this.version}`;
this.description = this.version;
this.resourceUri = vscode.Uri.file(dependencyPath);
}
2022-02-25 18:37:55 -06:00
}
export class DependencyFile extends vscode.TreeItem {
2022-02-25 19:37:09 -06:00
constructor(
readonly label: string,
readonly dependencyPath: string,
readonly parent: Dependency | DependencyFile,
public readonly collapsibleState: vscode.TreeItemCollapsibleState
) {
super(vscode.Uri.file(dependencyPath), collapsibleState);
const isDir = fs.lstatSync(this.dependencyPath).isDirectory();
this.id = this.dependencyPath.toLowerCase();
if (!isDir) {
2022-02-25 19:37:09 -06:00
this.command = { command: "vscode.open",
2022-07-17 10:38:56 -05:00
title: "Open File",
arguments: [vscode.Uri.file(this.dependencyPath)],
2022-02-25 19:37:09 -06:00
};
}}
2022-02-25 18:37:55 -06:00
}
2022-07-17 10:38:56 -05:00
export type DependencyId = { id: string };