feat:将调用node.js的fs模块改为vscode官方的API
- 这样可以避免用户本地没有node环境导致插件无法运行的原因
This commit is contained in:
@ -1,5 +1,4 @@
|
|||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
import * as fs from "fs";
|
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,21 +20,31 @@ export async function createFile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileUri = vscode.Uri.file(absolutePath);
|
||||||
|
|
||||||
// 检测文件是否已存在
|
// 检测文件是否已存在
|
||||||
if (fs.existsSync(absolutePath)) {
|
try {
|
||||||
|
await vscode.workspace.fs.stat(fileUri);
|
||||||
throw new Error(`文件已存在: ${absolutePath}`);
|
throw new Error(`文件已存在: ${absolutePath}`);
|
||||||
|
} catch (error: any) {
|
||||||
|
// 如果文件不存在,继续创建
|
||||||
|
if (error.code !== 'FileNotFound') {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确保目录存在
|
// 确保目录存在
|
||||||
const dirPath = path.dirname(absolutePath);
|
const dirPath = path.dirname(absolutePath);
|
||||||
if (!fs.existsSync(dirPath)) {
|
const dirUri = vscode.Uri.file(dirPath);
|
||||||
fs.mkdirSync(dirPath, {
|
try {
|
||||||
recursive: true,
|
await vscode.workspace.fs.stat(dirUri);
|
||||||
});
|
} catch {
|
||||||
|
await vscode.workspace.fs.createDirectory(dirUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建文件
|
// 创建文件
|
||||||
fs.writeFileSync(absolutePath, content, "utf-8");
|
const contentBytes = Buffer.from(content, "utf-8");
|
||||||
|
await vscode.workspace.fs.writeFile(fileUri, contentBytes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -62,14 +71,17 @@ export async function createOrOverwriteFile(
|
|||||||
|
|
||||||
// 确保目录存在
|
// 确保目录存在
|
||||||
const dirPath = path.dirname(absolutePath);
|
const dirPath = path.dirname(absolutePath);
|
||||||
if (!fs.existsSync(dirPath)) {
|
const dirUri = vscode.Uri.file(dirPath);
|
||||||
fs.mkdirSync(dirPath, {
|
try {
|
||||||
recursive: true,
|
await vscode.workspace.fs.stat(dirUri);
|
||||||
});
|
} catch {
|
||||||
|
await vscode.workspace.fs.createDirectory(dirUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建或覆盖文件
|
// 创建或覆盖文件
|
||||||
fs.writeFileSync(absolutePath, content, "utf-8");
|
const fileUri = vscode.Uri.file(absolutePath);
|
||||||
|
const contentBytes = Buffer.from(content, "utf-8");
|
||||||
|
await vscode.workspace.fs.writeFile(fileUri, contentBytes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -91,18 +103,25 @@ export async function createDirectory(dirPath: string): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dirUri = vscode.Uri.file(absolutePath);
|
||||||
|
|
||||||
// 检测创建目录是否存在
|
// 检测创建目录是否存在
|
||||||
if (fs.existsSync(absolutePath)) {
|
try {
|
||||||
const state = fs.statSync(absolutePath);
|
const stat = await vscode.workspace.fs.stat(dirUri);
|
||||||
if (state.isDirectory()) {
|
if (stat.type === vscode.FileType.Directory) {
|
||||||
throw new Error(`目录已存在: ${absolutePath}`);
|
throw new Error(`目录已存在: ${absolutePath}`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`路径已存在且不是目录: ${absolutePath}`);
|
throw new Error(`路径已存在且不是目录: ${absolutePath}`);
|
||||||
}
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
// 如果目录不存在,继续创建
|
||||||
|
if (error.code !== 'FileNotFound') {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建目录
|
// 创建目录
|
||||||
fs.mkdirSync(absolutePath, { recursive: true });
|
await vscode.workspace.fs.createDirectory(dirUri);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -146,19 +165,20 @@ export async function deleteFile(filePath: string): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileUri = vscode.Uri.file(absolutePath);
|
||||||
|
|
||||||
// 检查文件是否存在
|
// 检查文件是否存在
|
||||||
if (!fs.existsSync(absolutePath)) {
|
try {
|
||||||
|
const stat = await vscode.workspace.fs.stat(fileUri);
|
||||||
|
if (stat.type !== vscode.FileType.File) {
|
||||||
|
throw new Error(`路径不是文件: ${absolutePath}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
throw new Error(`文件不存在: ${absolutePath}`);
|
throw new Error(`文件不存在: ${absolutePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否是文件
|
|
||||||
const stats = fs.statSync(absolutePath);
|
|
||||||
if (!stats.isFile()) {
|
|
||||||
throw new Error(`路径不是文件: ${absolutePath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除文件
|
// 删除文件
|
||||||
fs.unlinkSync(absolutePath);
|
await vscode.workspace.fs.delete(fileUri);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -181,19 +201,21 @@ export async function updateFile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileUri = vscode.Uri.file(absolutePath);
|
||||||
|
|
||||||
// 检查文件是否存在
|
// 检查文件是否存在
|
||||||
if (!fs.existsSync(absolutePath)) {
|
try {
|
||||||
|
const stat = await vscode.workspace.fs.stat(fileUri);
|
||||||
|
if (stat.type !== vscode.FileType.File) {
|
||||||
|
throw new Error(`路径不是文件: ${absolutePath}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
throw new Error(`文件不存在: ${absolutePath}`);
|
throw new Error(`文件不存在: ${absolutePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否是文件内容
|
|
||||||
const state = fs.statSync(absolutePath);
|
|
||||||
if (!state.isFile()) {
|
|
||||||
throw new Error(`路径不是文件: ${absolutePath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改文件内容
|
// 修改文件内容
|
||||||
fs.writeFileSync(absolutePath, content, "utf-8");
|
const contentBytes = Buffer.from(content, "utf-8");
|
||||||
|
await vscode.workspace.fs.writeFile(fileUri, contentBytes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -218,13 +240,21 @@ export async function appendToFile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查文件是否存在
|
const fileUri = vscode.Uri.file(absolutePath);
|
||||||
if (!fs.existsSync(absolutePath)) {
|
|
||||||
|
// 检查文件是否存在并读取原内容
|
||||||
|
let existingContent = "";
|
||||||
|
try {
|
||||||
|
const contentBytes = await vscode.workspace.fs.readFile(fileUri);
|
||||||
|
existingContent = Buffer.from(contentBytes).toString("utf-8");
|
||||||
|
} catch (error) {
|
||||||
throw new Error(`文件不存在: ${absolutePath}`);
|
throw new Error(`文件不存在: ${absolutePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 追加内容
|
// 追加内容
|
||||||
fs.appendFileSync(absolutePath, content, "utf-8");
|
const newContent = existingContent + content;
|
||||||
|
const contentBytes = Buffer.from(newContent, "utf-8");
|
||||||
|
await vscode.workspace.fs.writeFile(fileUri, contentBytes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -248,13 +278,16 @@ export async function replaceFile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查文件是否存在
|
const fileUri = vscode.Uri.file(absolutePath);
|
||||||
if (!fs.existsSync(absolutePath)) {
|
|
||||||
throw new Error(`文件不存在: ${absolutePath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 读取文件内容
|
// 读取文件内容
|
||||||
const fileContent = fs.readFileSync(absolutePath, "utf-8");
|
let fileContent: string;
|
||||||
|
try {
|
||||||
|
const contentBytes = await vscode.workspace.fs.readFile(fileUri);
|
||||||
|
fileContent = Buffer.from(contentBytes).toString("utf-8");
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`文件不存在: ${absolutePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
// 转义特殊字符,将字符串作为字面量处理
|
// 转义特殊字符,将字符串作为字面量处理
|
||||||
const escapeRegExp = (str: string) => {
|
const escapeRegExp = (str: string) => {
|
||||||
@ -276,7 +309,8 @@ export async function replaceFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 写回文件
|
// 写回文件
|
||||||
fs.writeFileSync(absolutePath, newContent, "utf-8");
|
const contentBytes = Buffer.from(newContent, "utf-8");
|
||||||
|
await vscode.workspace.fs.writeFile(fileUri, contentBytes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -300,20 +334,26 @@ export async function insertAtLine(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查文件是否存在
|
const fileUri = vscode.Uri.file(absolutePath);
|
||||||
if (!fs.existsSync(absolutePath)) {
|
|
||||||
|
// 读取文件内容
|
||||||
|
let fileContent: string;
|
||||||
|
try {
|
||||||
|
const contentBytes = await vscode.workspace.fs.readFile(fileUri);
|
||||||
|
fileContent = Buffer.from(contentBytes).toString("utf-8");
|
||||||
|
} catch (error) {
|
||||||
throw new Error(`文件不存在: ${absolutePath}`);
|
throw new Error(`文件不存在: ${absolutePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取文件内容
|
|
||||||
const fileContent = fs.readFileSync(absolutePath, "utf-8");
|
|
||||||
const lines = fileContent.split("\n");
|
const lines = fileContent.split("\n");
|
||||||
|
|
||||||
// 插入内容
|
// 插入内容
|
||||||
lines.splice(lineNumber, 0, content);
|
lines.splice(lineNumber, 0, content);
|
||||||
|
|
||||||
// 写回文件
|
// 写回文件
|
||||||
fs.writeFileSync(absolutePath, lines.join("\n"), "utf-8");
|
const newContent = lines.join("\n");
|
||||||
|
const newContentBytes = Buffer.from(newContent, "utf-8");
|
||||||
|
await vscode.workspace.fs.writeFile(fileUri, newContentBytes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -345,24 +385,41 @@ export async function renameFile(
|
|||||||
throw new Error("没有打开的工作区,无法重命名相对路径的文件");
|
throw new Error("没有打开的工作区,无法重命名相对路径的文件");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const oldUri = vscode.Uri.file(absoluteOldPath);
|
||||||
|
const newUri = vscode.Uri.file(absoluteNewPath);
|
||||||
|
|
||||||
// 检查原文件是否存在
|
// 检查原文件是否存在
|
||||||
if (!fs.existsSync(absoluteOldPath)) {
|
try {
|
||||||
|
await vscode.workspace.fs.stat(oldUri);
|
||||||
|
} catch (error) {
|
||||||
throw new Error(`文件不存在: ${absoluteOldPath}`);
|
throw new Error(`文件不存在: ${absoluteOldPath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查新文件名是否已存在
|
// 检查新文件名是否已存在
|
||||||
if (fs.existsSync(absoluteNewPath)) {
|
try {
|
||||||
|
await vscode.workspace.fs.stat(newUri);
|
||||||
throw new Error(`目标文件已存在: ${absoluteNewPath}`);
|
throw new Error(`目标文件已存在: ${absoluteNewPath}`);
|
||||||
|
} catch (error: any) {
|
||||||
|
// 如果文件不存在,继续重命名
|
||||||
|
if (error.code !== 'FileNotFound' && !error.message.includes('目标文件已存在')) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
if (error.message.includes('目标文件已存在')) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确保目标目录存在
|
// 确保目标目录存在
|
||||||
const newDir = path.dirname(absoluteNewPath);
|
const newDir = path.dirname(absoluteNewPath);
|
||||||
if (!fs.existsSync(newDir)) {
|
const newDirUri = vscode.Uri.file(newDir);
|
||||||
fs.mkdirSync(newDir, { recursive: true });
|
try {
|
||||||
|
await vscode.workspace.fs.stat(newDirUri);
|
||||||
|
} catch {
|
||||||
|
await vscode.workspace.fs.createDirectory(newDirUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重命名文件
|
// 重命名文件
|
||||||
fs.renameSync(absoluteOldPath, absoluteNewPath);
|
await vscode.workspace.fs.rename(oldUri, newUri, { overwrite: false });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
import * as fs from "fs";
|
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import { spawn } from "child_process";
|
import { spawn } from "child_process";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
@ -107,13 +106,16 @@ export async function checkVerilogProject(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 检查项目路径是否存在
|
// 检查项目路径是否存在
|
||||||
if (!fs.existsSync(projectPath)) {
|
const projectUri = vscode.Uri.file(projectPath);
|
||||||
|
try {
|
||||||
|
await vscode.workspace.fs.stat(projectUri);
|
||||||
|
} catch (error) {
|
||||||
result.errors.push(`项目路径不存在: ${projectPath}`);
|
result.errors.push(`项目路径不存在: ${projectPath}`);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找所有 Verilog 文件 (.v, .sv)
|
// 查找所有 Verilog 文件 (.v, .sv)
|
||||||
const verilogFiles = findVerilogFiles(projectPath);
|
const verilogFiles = await findVerilogFiles(projectPath);
|
||||||
result.allVerilogFiles = verilogFiles;
|
result.allVerilogFiles = verilogFiles;
|
||||||
|
|
||||||
if (verilogFiles.length === 0) {
|
if (verilogFiles.length === 0) {
|
||||||
@ -123,7 +125,9 @@ export async function checkVerilogProject(
|
|||||||
|
|
||||||
// 分析文件内容,查找 top module 和 testbench
|
// 分析文件内容,查找 top module 和 testbench
|
||||||
for (const file of verilogFiles) {
|
for (const file of verilogFiles) {
|
||||||
const content = fs.readFileSync(file, "utf-8");
|
const fileUri = vscode.Uri.file(file);
|
||||||
|
const contentBytes = await vscode.workspace.fs.readFile(fileUri);
|
||||||
|
const content = Buffer.from(contentBytes).toString("utf-8");
|
||||||
const fileName = path.basename(file).toLowerCase();
|
const fileName = path.basename(file).toLowerCase();
|
||||||
|
|
||||||
// 检查是否是 testbench 文件
|
// 检查是否是 testbench 文件
|
||||||
@ -169,23 +173,23 @@ export async function checkVerilogProject(
|
|||||||
/**
|
/**
|
||||||
* 递归查找目录下所有 Verilog 文件
|
* 递归查找目录下所有 Verilog 文件
|
||||||
*/
|
*/
|
||||||
function findVerilogFiles(dir: string): string[] {
|
async function findVerilogFiles(dir: string): Promise<string[]> {
|
||||||
const verilogFiles: string[] = [];
|
const verilogFiles: string[] = [];
|
||||||
|
|
||||||
function searchDir(currentDir: string) {
|
async function searchDir(currentDir: string) {
|
||||||
const files = fs.readdirSync(currentDir);
|
const dirUri = vscode.Uri.file(currentDir);
|
||||||
|
const entries = await vscode.workspace.fs.readDirectory(dirUri);
|
||||||
|
|
||||||
for (const file of files) {
|
for (const [fileName, fileType] of entries) {
|
||||||
const filePath = path.join(currentDir, file);
|
const filePath = path.join(currentDir, fileName);
|
||||||
const stat = fs.statSync(filePath);
|
|
||||||
|
|
||||||
if (stat.isDirectory()) {
|
if (fileType === vscode.FileType.Directory) {
|
||||||
// 跳过 node_modules 等目录
|
// 跳过 node_modules 等目录
|
||||||
if (!file.startsWith(".") && file !== "node_modules") {
|
if (!fileName.startsWith(".") && fileName !== "node_modules") {
|
||||||
searchDir(filePath);
|
await searchDir(filePath);
|
||||||
}
|
}
|
||||||
} else if (stat.isFile()) {
|
} else if (fileType === vscode.FileType.File) {
|
||||||
const ext = path.extname(file).toLowerCase();
|
const ext = path.extname(fileName).toLowerCase();
|
||||||
if (ext === ".v" || ext === ".sv") {
|
if (ext === ".v" || ext === ".sv") {
|
||||||
verilogFiles.push(filePath);
|
verilogFiles.push(filePath);
|
||||||
}
|
}
|
||||||
@ -193,14 +197,14 @@ function findVerilogFiles(dir: string): string[] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
searchDir(dir);
|
await searchDir(dir);
|
||||||
return verilogFiles;
|
return verilogFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 iverilog 可执行文件路径
|
* 获取 iverilog 可执行文件路径
|
||||||
*/
|
*/
|
||||||
function getIverilogPath(extensionPath: string): string {
|
async function getIverilogPath(extensionPath: string): Promise<string> {
|
||||||
const platform = process.platform;
|
const platform = process.platform;
|
||||||
let iverilogBin = "";
|
let iverilogBin = "";
|
||||||
|
|
||||||
@ -214,17 +218,19 @@ function getIverilogPath(extensionPath: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 如果插件包中没有,尝试使用系统安装的 iverilog
|
// 如果插件包中没有,尝试使用系统安装的 iverilog
|
||||||
if (!fs.existsSync(iverilogBin)) {
|
const iverilogUri = vscode.Uri.file(iverilogBin);
|
||||||
|
try {
|
||||||
|
await vscode.workspace.fs.stat(iverilogUri);
|
||||||
|
return iverilogBin;
|
||||||
|
} catch {
|
||||||
return "iverilog"; // 使用系统 PATH 中的 iverilog
|
return "iverilog"; // 使用系统 PATH 中的 iverilog
|
||||||
}
|
}
|
||||||
|
|
||||||
return iverilogBin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 vvp 可执行文件路径
|
* 获取 vvp 可执行文件路径
|
||||||
*/
|
*/
|
||||||
function getVvpPath(extensionPath: string): string {
|
async function getVvpPath(extensionPath: string): Promise<string> {
|
||||||
const platform = process.platform;
|
const platform = process.platform;
|
||||||
let vvpBin = "";
|
let vvpBin = "";
|
||||||
|
|
||||||
@ -238,11 +244,13 @@ function getVvpPath(extensionPath: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 如果插件包中没有,尝试使用系统安装的 vvp
|
// 如果插件包中没有,尝试使用系统安装的 vvp
|
||||||
if (!fs.existsSync(vvpBin)) {
|
const vvpUri = vscode.Uri.file(vvpBin);
|
||||||
|
try {
|
||||||
|
await vscode.workspace.fs.stat(vvpUri);
|
||||||
|
return vvpBin;
|
||||||
|
} catch {
|
||||||
return "vvp"; // 使用系统 PATH 中的 vvp
|
return "vvp"; // 使用系统 PATH 中的 vvp
|
||||||
}
|
}
|
||||||
|
|
||||||
return vvpBin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -264,8 +272,8 @@ export async function generateVCD(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 获取 iverilog 和 vvp 路径
|
// 2. 获取 iverilog 和 vvp 路径
|
||||||
const iverilogPath = getIverilogPath(extensionPath);
|
const iverilogPath = await getIverilogPath(extensionPath);
|
||||||
const vvpPath = getVvpPath(extensionPath);
|
const vvpPath = await getVvpPath(extensionPath);
|
||||||
|
|
||||||
// 3. 准备输出路径
|
// 3. 准备输出路径
|
||||||
const outputDir = projectPath;
|
const outputDir = projectPath;
|
||||||
@ -320,7 +328,11 @@ export async function generateVCD(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 8. 查找生成的 VCD 文件
|
// 8. 查找生成的 VCD 文件
|
||||||
const vcdFiles = fs.readdirSync(projectPath).filter(file => file.endsWith('.vcd'));
|
const projectUri = vscode.Uri.file(projectPath);
|
||||||
|
const entries = await vscode.workspace.fs.readDirectory(projectUri);
|
||||||
|
const vcdFiles = entries
|
||||||
|
.filter(([fileName, fileType]) => fileType === vscode.FileType.File && fileName.endsWith('.vcd'))
|
||||||
|
.map(([fileName]) => fileName);
|
||||||
|
|
||||||
if (vcdFiles.length === 0) {
|
if (vcdFiles.length === 0) {
|
||||||
return {
|
return {
|
||||||
@ -335,9 +347,9 @@ export async function generateVCD(
|
|||||||
|
|
||||||
// 9. 清理中间文件
|
// 9. 清理中间文件
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync(outputFile)) {
|
const outputUri = vscode.Uri.file(outputFile);
|
||||||
fs.unlinkSync(outputFile);
|
await vscode.workspace.fs.stat(outputUri);
|
||||||
}
|
await vscode.workspace.fs.delete(outputUri);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 忽略清理错误
|
// 忽略清理错误
|
||||||
}
|
}
|
||||||
@ -364,10 +376,13 @@ export async function checkIverilogAvailable(
|
|||||||
extensionPath: string
|
extensionPath: string
|
||||||
): Promise<{ available: boolean; version?: string; message: string }> {
|
): Promise<{ available: boolean; version?: string; message: string }> {
|
||||||
try {
|
try {
|
||||||
const iverilogPath = getIverilogPath(extensionPath);
|
const iverilogPath = await getIverilogPath(extensionPath);
|
||||||
|
|
||||||
// 检查文件是否存在
|
// 检查文件是否存在
|
||||||
if (!fs.existsSync(iverilogPath)) {
|
const iverilogUri = vscode.Uri.file(iverilogPath);
|
||||||
|
try {
|
||||||
|
await vscode.workspace.fs.stat(iverilogUri);
|
||||||
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
available: false,
|
available: false,
|
||||||
message: `iverilog 不可用。未找到文件: ${iverilogPath}`,
|
message: `iverilog 不可用。未找到文件: ${iverilogPath}`,
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
import * as fs from "fs";
|
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,19 +15,21 @@ export async function readFileContent(filePath: string): Promise<string> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查文件是否存在
|
const fileUri = vscode.Uri.file(absolutePath);
|
||||||
if (!fs.existsSync(absolutePath)) {
|
|
||||||
|
// 检查文件是否存在并获取文件类型
|
||||||
|
try {
|
||||||
|
const stat = await vscode.workspace.fs.stat(fileUri);
|
||||||
|
if (stat.type !== vscode.FileType.File) {
|
||||||
|
throw new Error(`路径不是文件: ${absolutePath}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
throw new Error(`文件不存在: ${absolutePath}`);
|
throw new Error(`文件不存在: ${absolutePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否是文件
|
|
||||||
const stats = fs.statSync(absolutePath);
|
|
||||||
if (!stats.isFile()) {
|
|
||||||
throw new Error(`路径不是文件: ${absolutePath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 读取文件内容
|
// 读取文件内容
|
||||||
const content = fs.readFileSync(absolutePath, "utf-8");
|
const contentBytes = await vscode.workspace.fs.readFile(fileUri);
|
||||||
|
const content = Buffer.from(contentBytes).toString("utf-8");
|
||||||
return content;
|
return content;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
@ -76,36 +77,38 @@ export async function readDirectory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dirUri = vscode.Uri.file(absolutePath);
|
||||||
|
|
||||||
// 检查目录是否存在
|
// 检查目录是否存在
|
||||||
if (!fs.existsSync(absolutePath)) {
|
try {
|
||||||
|
const stat = await vscode.workspace.fs.stat(dirUri);
|
||||||
|
if (stat.type !== vscode.FileType.Directory) {
|
||||||
|
throw new Error(`路径不是目录: ${absolutePath}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
throw new Error(`目录不存在: ${absolutePath}`);
|
throw new Error(`目录不存在: ${absolutePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const stats = fs.statSync(absolutePath);
|
|
||||||
if (!stats.isDirectory()) {
|
|
||||||
throw new Error(`路径不是目录: ${absolutePath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 读取目录内容
|
// 读取目录内容
|
||||||
const files = fs.readdirSync(absolutePath);
|
const entries = await vscode.workspace.fs.readDirectory(dirUri);
|
||||||
const results = [];
|
const results = [];
|
||||||
|
|
||||||
for (const file of files) {
|
for (const [fileName, fileType] of entries) {
|
||||||
const filePath = path.join(absolutePath, file);
|
if (fileType === vscode.FileType.File) {
|
||||||
const fileStats = fs.statSync(filePath);
|
|
||||||
|
|
||||||
if (fileStats.isFile()) {
|
|
||||||
// 如果指定了扩展名过滤
|
// 如果指定了扩展名过滤
|
||||||
if (extensions && extensions.length > 0) {
|
if (extensions && extensions.length > 0) {
|
||||||
const ext = path.extname(file);
|
const ext = path.extname(fileName);
|
||||||
if (!extensions.includes(ext)) {
|
if (!extensions.includes(ext)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const content = fs.readFileSync(filePath, "utf-8");
|
const filePath = path.join(absolutePath, fileName);
|
||||||
results.push({ path: file, content });
|
const fileUri = vscode.Uri.file(filePath);
|
||||||
|
const contentBytes = await vscode.workspace.fs.readFile(fileUri);
|
||||||
|
const content = Buffer.from(contentBytes).toString("utf-8");
|
||||||
|
results.push({ path: fileName, content });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 跳过无法读取的文件
|
// 跳过无法读取的文件
|
||||||
continue;
|
continue;
|
||||||
@ -122,13 +125,13 @@ export async function readDirectory(
|
|||||||
/**
|
/**
|
||||||
* 获取文件信息
|
* 获取文件信息
|
||||||
*/
|
*/
|
||||||
export function getFileInfo(filePath: string): {
|
export async function getFileInfo(filePath: string): Promise<{
|
||||||
exists: boolean;
|
exists: boolean;
|
||||||
isFile: boolean;
|
isFile: boolean;
|
||||||
isDirectory: boolean;
|
isDirectory: boolean;
|
||||||
size?: number;
|
size?: number;
|
||||||
extension?: string;
|
extension?: string;
|
||||||
} {
|
}> {
|
||||||
try {
|
try {
|
||||||
let absolutePath = filePath;
|
let absolutePath = filePath;
|
||||||
if (!path.isAbsolute(filePath)) {
|
if (!path.isAbsolute(filePath)) {
|
||||||
@ -138,22 +141,24 @@ export function getFileInfo(filePath: string): {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(absolutePath)) {
|
const fileUri = vscode.Uri.file(absolutePath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const stat = await vscode.workspace.fs.stat(fileUri);
|
||||||
|
return {
|
||||||
|
exists: true,
|
||||||
|
isFile: stat.type === vscode.FileType.File,
|
||||||
|
isDirectory: stat.type === vscode.FileType.Directory,
|
||||||
|
size: stat.size,
|
||||||
|
extension: path.extname(absolutePath),
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
exists: false,
|
exists: false,
|
||||||
isFile: false,
|
isFile: false,
|
||||||
isDirectory: false,
|
isDirectory: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const stats = fs.statSync(absolutePath);
|
|
||||||
return {
|
|
||||||
exists: true,
|
|
||||||
isFile: stats.isFile(),
|
|
||||||
isDirectory: stats.isDirectory(),
|
|
||||||
size: stats.size,
|
|
||||||
extension: path.extname(absolutePath),
|
|
||||||
};
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
exists: false,
|
exists: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user