Skip to content

Commit

Permalink
Revert "improve for workspace contains lots of main.tsp"
Browse files Browse the repository at this point in the history
This reverts commit 3b2da45.
  • Loading branch information
RodgeFu committed Sep 7, 2024
1 parent 3b2da45 commit dd499a4
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 85 deletions.
21 changes: 0 additions & 21 deletions packages/typespec-vscode/src/cache.ts

This file was deleted.

78 changes: 14 additions & 64 deletions packages/typespec-vscode/src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ResolveModuleHost } from "@typespec/compiler/module-resolver";
import { existsSync } from "fs";
import { readFile, realpath, stat } from "fs/promises";
import { dirname, isAbsolute, join, resolve } from "path";
import vscode, { ExtensionContext, commands, workspace } from "vscode";
Expand All @@ -9,7 +8,6 @@ import {
LanguageClient,
LanguageClientOptions,
} from "vscode-languageclient/node.js";
import { Cache } from "./cache.js";
import logger from "./extension-logger.js";
import { TypeSpecLogOutputChannel } from "./typespec-log-output-channel.js";
import { normalizeSlash } from "./utils.js";
Expand All @@ -23,7 +21,7 @@ const outputChannel = new TypeSpecLogOutputChannel("TypeSpec");
logger.outputChannel = outputChannel;

export async function activate(context: ExtensionContext) {
context.subscriptions.push(createTaskProvider());
context.subscriptions.push(await createTaskProvider());

context.subscriptions.push(
commands.registerCommand("typespec.showOutputChannel", () => {
Expand All @@ -44,27 +42,23 @@ export async function activate(context: ExtensionContext) {
);
}

function createTaskProvider() {
async function createTaskProvider() {
return vscode.tasks.registerTaskProvider("typespec", {
provideTasks: async () => {
logger.info("Providing tsp tasks");
const targetPathes = await vscode.workspace
.findFiles("**/main.tsp", "**/node_modules/**")
.findFiles("**/main.tsp")
.then((uris) =>
uris
.filter((uri) => uri.scheme === "file" && !uri.fsPath.includes("node_modules"))
.map((uri) => normalizeSlash(uri.fsPath))
);
logger.info(`Found ${targetPathes.length} main.tsp files`);
const cache = new Cache<string>();
const tasks: vscode.Task[] = [];
for (const targetPath of targetPathes) {
const cTask = await createTask(`compile - ${targetPath}`, targetPath, undefined, cache);
const cTask = await createTask(`compile - ${targetPath}`, targetPath);
if (cTask) tasks.push(cTask);
const wTask = await createTask(`watch - ${targetPath}`, targetPath, "--watch", cache);
const wTask = await createTask(`watch - ${targetPath}`, targetPath, "--watch");
if (wTask) tasks.push(wTask);
}
logger.info(`Provided ${tasks.length} tsp tasks`);
return tasks;
},
resolveTask: async (task: vscode.Task): Promise<vscode.Task | undefined> => {
Expand All @@ -84,12 +78,8 @@ function createTaskProvider() {
});
}

async function createTask(
name: string,
targetPath: string,
args?: string,
compilerCache?: Cache<string>
) {
async function createTask(name: string, targetPath: string, args?: string) {
logger.debug(`Creating tsp task with path as '${targetPath}'`);
let workspaceFolder = workspace.getWorkspaceFolder(vscode.Uri.file(targetPath))?.uri.fsPath;
if (!workspaceFolder) {
workspaceFolder = workspace.workspaceFolders?.[0]?.uri.fsPath ?? "";
Expand All @@ -104,16 +94,16 @@ async function createTask(
targetPath = variableResolver.resolve(targetPath);
targetPath = resolve(workspaceFolder, targetPath);
targetPath = normalizeSlash(variableResolver.resolve(targetPath));
logger.debug(`Task target path resolved as '${targetPath}'`);
// TODO: we don't expect this will be triggered so frequently, so we just resolve every time for now.
// Consider adding cache if we do see perf issue here.
const cli = await resolveTypeSpecCli(targetPath, compilerCache);
const cli = await resolveTypeSpecCli(targetPath);
if (!cli) return undefined;

let cmd = `${cli.command} ${cli.args?.join(" ") ?? ""} compile "${targetPath}" ${args === undefined ? "" : args}`;
logger.debug(`tsp compile task created '${targetPath}' with command: '${cmd}'`);
cmd = variableResolver.resolve(cmd);
logger.debug(
`Command of tsp compile task with targetPath "${targetPath}" is resolved to: ${cmd} with cwd "${workspaceFolder}"`
);
logger.debug(`tsp compile task command resolved to: ${cmd} with cwd "${workspaceFolder}"`);
return new vscode.Task(
{
type: "typespec",
Expand Down Expand Up @@ -192,10 +182,7 @@ async function launchLanguageClient(context: ExtensionContext) {
* @param absoluteTargetPath the path is expected to be absolute path and no further expanding or resolving needed.
* @returns
*/
async function resolveTypeSpecCli(
absoluteTargetPath: string,
compilerCache?: Cache<string>
): Promise<Executable | undefined> {
async function resolveTypeSpecCli(absoluteTargetPath: string): Promise<Executable | undefined> {
if (!isAbsolute(absoluteTargetPath)) {
logger.error(`Expect absolute path for resolving cli, but got ${absoluteTargetPath}`);
return undefined;
Expand All @@ -209,8 +196,8 @@ async function resolveTypeSpecCli(
? dirname(absoluteTargetPath)
: absoluteTargetPath;

const compilerPath = await resolveLocalCompilerSlim(baseDir, compilerCache);
if (!compilerPath || compilerPath.length === 0) {
const compilerPath = await resolveLocalCompiler(baseDir);
if (!compilerPath) {
const executable = process.platform === "win32" ? `tsp.cmd` : "tsp";
logger.debug(
`Can't resolve compiler path for tsp task, try to use default value ${executable}.`
Expand Down Expand Up @@ -291,43 +278,6 @@ async function resolveTypeSpecServer(context: ExtensionContext): Promise<Executa
return { command: "node", args: [serverPath, ...args], options };
}

/**
* Slim version of resolveLocalCompiler by simply checking the existence of "node_modules/@typespec/compiler"
* this can provide a much better performance which is important when we need to do compiler resolving lots of times (i.e. when providing built-in tsp tasks in task provider for all the main.tsp files in opened workspace which may be a lot)
* @param baseDir absolute path is expected and no further expanding or resolving needed. Please be aware that no check will be done to the param. It's caller's responsibility to ensure the param is valid.
* @param cache cache to store the resolved compiler path for each folder ("path" -> ".../node_modules/@typespec/compiler"). If provided, the cache will be used to speed up the resolving process.
* @returns the path of the .../node_modules/@typespec/compiler folder or "" if not found.
*/
async function resolveLocalCompilerSlim(
absoluteBaseDir: string,
cache?: Cache<string>
): Promise<string> {
let curDir = absoluteBaseDir;
let lastDir = "";
const pathToCache: string[] = [];
while (curDir !== lastDir) {
const found = cache?.get(curDir);
// "" is also a valid cache value, so we need to check undefined explicitly.
if (found !== undefined) {
cache?.setAll(pathToCache, found);
return found;
}

pathToCache.push(curDir);
const compilerPath = join(curDir, "node_modules/@typespec/compiler");
// Just check existence should be enough. We don't expect a file named "@typespec/compiler" to be under node_modules folder...
// Also did some rough perf test and the existsSync() has better perf than access() and stat() in most cases.
if (existsSync(compilerPath)) {
cache?.setAll(pathToCache, compilerPath);
return compilerPath;
}
lastDir = curDir;
curDir = dirname(curDir);
}
cache?.setAll(pathToCache, "");
return "";
}

async function resolveLocalCompiler(baseDir: string): Promise<string | undefined> {
// dynamic import required when unbundled as this module is CommonJS for
// VS Code and the module-resolver is an ES module.
Expand Down

0 comments on commit dd499a4

Please sign in to comment.