diff options
| author | Bruno Ortiz <brunortiz11@gmail.com> | 2023-04-02 21:58:20 -0300 |
|---|---|---|
| committer | Bruno Ortiz <brunortiz11@gmail.com> | 2023-05-02 10:56:09 -0300 |
| commit | 09e0a00d3648eb4080d16f07c6dae73f7c73c431 (patch) | |
| tree | 4cbc611accb6cd706ab2692f824a5359c88936ff /editors/code/src | |
| parent | 1201b156d839ac5b5cc7bca1ea1c1f0cf6fbf6a9 (diff) | |
| download | rust-09e0a00d3648eb4080d16f07c6dae73f7c73c431.tar.gz rust-09e0a00d3648eb4080d16f07c6dae73f7c73c431.zip | |
fetching dependencies from the server
Diffstat (limited to 'editors/code/src')
| -rw-r--r-- | editors/code/src/commands.ts | 8 | ||||
| -rw-r--r-- | editors/code/src/ctx.ts | 48 | ||||
| -rw-r--r-- | editors/code/src/dependencies_provider.ts | 77 | ||||
| -rw-r--r-- | editors/code/src/toolchain.ts | 75 |
4 files changed, 56 insertions, 152 deletions
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index 70eeab897c9..7fe32754c90 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -272,19 +272,19 @@ export function revealDependency(ctx: CtxInit): Cmd { const rootPath = vscode.workspace.workspaceFolders![0].uri.fsPath; const documentPath = editor.document.uri.fsPath; if (documentPath.startsWith(rootPath)) return; - const dep = ctx.dependencies.getDependency(documentPath); + const dep = ctx.dependencies?.getDependency(documentPath); if (dep) { - await ctx.treeView.reveal(dep, { select: true, expand: true }); + await ctx.treeView?.reveal(dep, { select: true, expand: true }); } else { let documentPath = editor.document.uri.fsPath; const parentChain: DependencyId[] = [{ id: documentPath.toLowerCase() }]; do { documentPath = path.dirname(documentPath); parentChain.push({ id: documentPath.toLowerCase() }); - } while (!ctx.dependencies.contains(documentPath)); + } while (!ctx.dependencies?.contains(documentPath)); parentChain.reverse(); for (const idx in parentChain) { - await ctx.treeView.reveal(parentChain[idx], { select: true, expand: true }); + await ctx.treeView?.reveal(parentChain[idx], { select: true, expand: true }); } } }; diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index feb39198c22..d62716c26db 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -91,19 +91,25 @@ export class Ctx { private commandFactories: Record<string, CommandFactory>; private commandDisposables: Disposable[]; private unlinkedFiles: vscode.Uri[]; - readonly dependencies: RustDependenciesProvider; - readonly treeView: vscode.TreeView<Dependency | DependencyFile | DependencyId>; + private _dependencies: RustDependenciesProvider | undefined; + private _treeView: vscode.TreeView<Dependency | DependencyFile | DependencyId> | undefined; get client() { return this._client; } + get treeView() { + return this._treeView; + } + + get dependencies() { + return this._dependencies; + } + constructor( readonly extCtx: vscode.ExtensionContext, commandFactories: Record<string, CommandFactory>, workspace: Workspace, - dependencies: RustDependenciesProvider, - treeView: vscode.TreeView<Dependency | DependencyFile | DependencyId> ) { extCtx.subscriptions.push(this); this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); @@ -112,9 +118,6 @@ export class Ctx { this.commandDisposables = []; this.commandFactories = commandFactories; this.unlinkedFiles = []; - this.dependencies = dependencies; - this.treeView = treeView; - this.state = new PersistentState(extCtx.globalState); this.config = new Config(extCtx); @@ -123,13 +126,6 @@ export class Ctx { this.setServerStatus({ health: "stopped", }); - vscode.window.onDidChangeActiveTextEditor((e) => { - if (e && isRustEditor(e)) { - execRevealDependency(e).catch((reason) => { - void vscode.window.showErrorMessage(`Dependency error: ${reason}`); - }); - } - }); } dispose() { @@ -267,6 +263,28 @@ export class Ctx { } await client.start(); this.updateCommands(); + this.prepareTreeDependenciesView(client); + } + + private prepareTreeDependenciesView(client: lc.LanguageClient) { + const ctxInit: CtxInit = { + ...this, + client: client + }; + const rootPath = vscode.workspace.workspaceFolders![0].uri.fsPath; + this._dependencies = new RustDependenciesProvider(rootPath, ctxInit); + this._treeView = vscode.window.createTreeView("rustDependencies", { + treeDataProvider: this._dependencies, + showCollapseAll: true, + }); + + vscode.window.onDidChangeActiveTextEditor((e) => { + if (e && isRustEditor(e)) { + execRevealDependency(e).catch((reason) => { + void vscode.window.showErrorMessage(`Dependency error: ${reason}`); + }); + } + }); } async restart() { @@ -369,7 +387,7 @@ export class Ctx { statusBar.color = undefined; statusBar.backgroundColor = undefined; statusBar.command = "rust-analyzer.stopServer"; - this.dependencies.refresh(); + this.dependencies?.refresh(); break; case "warning": if (status.message) { diff --git a/editors/code/src/dependencies_provider.ts b/editors/code/src/dependencies_provider.ts index 48d51523e86..195f41417dd 100644 --- a/editors/code/src/dependencies_provider.ts +++ b/editors/code/src/dependencies_provider.ts @@ -1,23 +1,16 @@ import * as vscode from "vscode"; import * as fspath from "path"; import * as fs from "fs"; -import * as os from "os"; -import { activeToolchain, Cargo, Crate, getRustcVersion } from "./toolchain"; -import { Ctx } from "./ctx"; -import { setFlagsFromString } from "v8"; +import { CtxInit } from "./ctx"; import * as ra from "./lsp_ext"; - -const debugOutput = vscode.window.createOutputChannel("Debug"); +import { FetchDependencyGraphResult } from "./lsp_ext"; export class RustDependenciesProvider - implements vscode.TreeDataProvider<Dependency | DependencyFile> -{ - cargo: Cargo; + implements vscode.TreeDataProvider<Dependency | DependencyFile> { dependenciesMap: { [id: string]: Dependency | DependencyFile }; - ctx: Ctx; + ctx: CtxInit; - constructor(private readonly workspaceRoot: string, ctx: Ctx) { - this.cargo = new Cargo(this.workspaceRoot || ".", debugOutput); + constructor(private readonly workspaceRoot: string, ctx: CtxInit) { this.dependenciesMap = {}; this.ctx = ctx; } @@ -62,7 +55,6 @@ export class RustDependenciesProvider void vscode.window.showInformationMessage("No dependency in empty workspace"); return Promise.resolve([]); } - if (element) { const files = fs.readdirSync(element.dependencyPath).map((fileName) => { const filePath = fspath.join(element.dependencyPath, fileName); @@ -81,59 +73,26 @@ export class RustDependenciesProvider } private async getRootDependencies(): Promise<Dependency[]> { - const crates = await this.ctx.client.sendRequest(ra.fetchDependencyGraph, {}); - - const registryDir = fspath.join(os.homedir(), ".cargo", "registry", "src"); - const basePath = fspath.join(registryDir, fs.readdirSync(registryDir)[0]); - const deps = await this.getDepsInCartoTree(basePath); - const stdlib = await this.getStdLib(); - this.dependenciesMap[stdlib.dependencyPath.toLowerCase()] = stdlib; - return [stdlib].concat(deps); - } - - private async getStdLib(): Promise<Dependency> { - const toolchain = await activeToolchain(); - const rustVersion = await getRustcVersion(os.homedir()); - const stdlibPath = fspath.join( - os.homedir(), - ".rustup", - "toolchains", - toolchain, - "lib", - "rustlib", - "src", - "rust", - "library" - ); - const stdlib = new Dependency( - "stdlib", - rustVersion, - stdlibPath, - vscode.TreeItemCollapsibleState.Collapsed - ); - - return stdlib; - } - - private async getDepsInCartoTree(basePath: string): Promise<Dependency[]> { - const crates: Crate[] = await this.cargo.crates(); - const toDep = (moduleName: string, version: string): Dependency => { - const cratePath = fspath.join(basePath, `${moduleName}-${version}`); - return new Dependency( - moduleName, - version, - cratePath, - vscode.TreeItemCollapsibleState.Collapsed - ); - }; + const dependenciesResult: FetchDependencyGraphResult = await this.ctx.client.sendRequest(ra.fetchDependencyGraph, {}); + const crates = dependenciesResult.crates; const deps = crates.map((crate) => { - const dep = toDep(crate.name, crate.version); + const dep = this.toDep(crate.name, crate.version, crate.path); this.dependenciesMap[dep.dependencyPath.toLowerCase()] = dep; return dep; }); return deps; } + + private toDep(moduleName: string, version: string, path: string): Dependency { + // const cratePath = fspath.join(basePath, `${moduleName}-${version}`); + return new Dependency( + moduleName, + version, + path, + vscode.TreeItemCollapsibleState.Collapsed + ); + } } export class Dependency extends vscode.TreeItem { diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts index c068cfc3118..771f6bcba45 100644 --- a/editors/code/src/toolchain.ts +++ b/editors/code/src/toolchain.ts @@ -5,14 +5,8 @@ import * as readline from "readline"; import * as vscode from "vscode"; import { execute, log, memoizeAsync } from "./util"; -const TREE_LINE_PATTERN = new RegExp(/(.+)\sv(\d+\.\d+\.\d+)(?:\s\((.+)\))?/); const TOOLCHAIN_PATTERN = new RegExp(/(.*)\s\(.*\)/); -export interface Crate { - name: string; - version: string; -} - interface CompilationArtifact { fileName: string; name: string; @@ -30,7 +24,7 @@ export class Cargo { readonly rootFolder: string, readonly output: vscode.OutputChannel, readonly env: Record<string, string> - ) {} + ) { } // Made public for testing purposes static artifactSpec(args: readonly string[]): ArtifactSpec { @@ -104,40 +98,6 @@ export class Cargo { return artifacts[0].fileName; } - async crates(): Promise<Crate[]> { - const pathToCargo = await cargoPath(); - return await new Promise((resolve, reject) => { - const crates: Crate[] = []; - - const cargo = cp.spawn(pathToCargo, ["tree", "--prefix", "none"], { - stdio: ["ignore", "pipe", "pipe"], - cwd: this.rootFolder, - }); - const rl = readline.createInterface({ input: cargo.stdout }); - rl.on("line", (line) => { - const match = line.match(TREE_LINE_PATTERN); - if (match) { - const name = match[1]; - const version = match[2]; - const extraInfo = match[3]; - // ignore duplicates '(*)' and path dependencies - if (this.shouldIgnore(extraInfo)) { - return; - } - crates.push({ name, version }); - } - }); - cargo.on("exit", (exitCode, _) => { - if (exitCode === 0) resolve(crates); - else reject(new Error(`exit code: ${exitCode}.`)); - }); - }); - } - - private shouldIgnore(extraInfo: string): boolean { - return extraInfo !== undefined && (extraInfo === "*" || path.isAbsolute(extraInfo)); - } - private async runCargo( cargoArgs: string[], onStdoutJson: (obj: any) => void, @@ -169,29 +129,6 @@ export class Cargo { } } -export async function activeToolchain(): Promise<string> { - const pathToRustup = await rustupPath(); - return await new Promise((resolve, reject) => { - const execution = cp.spawn(pathToRustup, ["show", "active-toolchain"], { - stdio: ["ignore", "pipe", "pipe"], - cwd: os.homedir(), - }); - const rl = readline.createInterface({ input: execution.stdout }); - - let currToolchain: string | undefined = undefined; - rl.on("line", (line) => { - const match = line.match(TOOLCHAIN_PATTERN); - if (match) { - currToolchain = match[1]; - } - }); - execution.on("exit", (exitCode, _) => { - if (exitCode === 0 && currToolchain) resolve(currToolchain); - else reject(new Error(`exit code: ${exitCode}.`)); - }); - }); -} - /** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/ export async function getSysroot(dir: string): Promise<string> { const rustcPath = await getPathForExecutable("rustc"); @@ -210,16 +147,6 @@ export async function getRustcId(dir: string): Promise<string> { return rx.exec(data)![1]; } -export async function getRustcVersion(dir: string): Promise<string> { - const rustcPath = await getPathForExecutable("rustc"); - - // do not memoize the result because the toolchain may change between runs - const data = await execute(`${rustcPath} -V`, { cwd: dir }); - const rx = /(\d\.\d+\.\d+)/; - - return rx.exec(data)![1]; -} - /** Mirrors `toolchain::cargo()` implementation */ export function cargoPath(): Promise<string> { return getPathForExecutable("cargo"); |
