Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions editors/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@
"default": "qihe",
"description": "%configuration.qihe.command.description%"
},
"vizsla.qihe.autoConfigureArgsFromManifest": {
"type": "boolean",
"default": true,
"description": "%configuration.qihe.autoConfigureArgsFromManifest.description%"
},
"vizsla.qihe.compileArgs": {
"type": "array",
"items": {
Expand Down
1 change: 1 addition & 0 deletions editors/vscode/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"configuration.server.cwd.description": "Working directory for the Vizsla language server process. Defaults to the first workspace folder.",
"configuration.server.additionalArgs.description": "Additional arguments appended when launching the Vizsla language server.",
"configuration.qihe.command.description": "Command used to invoke Qihe. It must be available in the environment PATH seen by VS Code.",
"configuration.qihe.autoConfigureArgsFromManifest.description": "Automatically add Qihe compile mode and forwarded slang options from the Vizsla project manifest. Disable this to provide those options manually through Qihe compile and run arguments.",
"configuration.qihe.compileArgs.description": "Arguments inserted after `qihe compile`. Use this for compile mode selection or forwarded `slang` options such as `--mode sv -- -I include`.",
"configuration.qihe.runArgs.description": "Arguments inserted after `qihe run` when the Qihe analysis button is used.",
"configuration.files.excludeDirs.markdownDescription": "Workspace-relative directories ignored by Vizsla. Globs are not supported; add matching patterns to VS Code `files.watcherExclude` if needed.",
Expand Down
1 change: 1 addition & 0 deletions editors/vscode/package.nls.zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"configuration.server.cwd.description": "Vizsla 语言服务器进程的工作目录。默认使用第一个工作区文件夹。",
"configuration.server.additionalArgs.description": "启动 Vizsla 语言服务器时追加的额外参数。",
"configuration.qihe.command.description": "用于调用 Qihe 的命令。它必须在 VS Code 可见的环境 PATH 中可用。",
"configuration.qihe.autoConfigureArgsFromManifest.description": "根据 Vizsla 项目配置文件自动添加 Qihe 编译模式和转发给 slang 的选项。关闭后可通过 Qihe 编译和运行参数手动提供这些选项。",
"configuration.qihe.compileArgs.description": "插入到 `qihe compile` 之后的参数。可用于选择编译模式,或转发 `slang` 选项,例如 `--mode sv -- -I include`。",
"configuration.qihe.runArgs.description": "使用 Qihe 分析按钮时,插入到 `qihe run` 之后的参数。",
"configuration.files.excludeDirs.markdownDescription": "Vizsla 忽略的工作区相对目录。不支持 glob;如需匹配模式,请添加到 VS Code `files.watcherExclude`。",
Expand Down
2 changes: 2 additions & 0 deletions editors/vscode/src/profiling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ function readVizslaInitializationOptions(): Record<string, unknown> {
},
signature_help_params_only: config.get('signature.help.params.only') ?? false,
qihe_command: config.get('qihe.command') ?? 'qihe',
qihe_autoConfigureArgsFromManifest:
config.get('qihe.autoConfigureArgsFromManifest') ?? true,
qihe_compileArgs: config.get('qihe.compileArgs') ?? [],
qihe_runArgs: config.get('qihe.runArgs') ?? ['-g', 'std'],
};
Expand Down
1 change: 1 addition & 0 deletions editors/vscode/test/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ test('contributes settings for the complete Vizsla user configuration surface',
'vizsla.server.cwd',
'vizsla.server.additionalArgs',
'vizsla.qihe.command',
'vizsla.qihe.autoConfigureArgsFromManifest',
'vizsla.qihe.compileArgs',
'vizsla.qihe.runArgs',
'vizsla.files.excludeDirs',
Expand Down
54 changes: 41 additions & 13 deletions src/config/user_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ fn default_true() -> bool {
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct QiheConfig {
pub(crate) command: String,
pub(crate) auto_configure_args_from_manifest: bool,
pub(crate) compile_args: Vec<String>,
pub(crate) run_args: Vec<String>,
}
Expand Down Expand Up @@ -194,6 +195,7 @@ config_data! {
signature_help_params_only: bool = false,

qihe_command: String = DEFAULT_QIHE_COMMAND.to_string(),
qihe_autoConfigureArgsFromManifest: bool = true,
qihe_compileArgs: Vec<String> = vec![],
qihe_runArgs: Vec<String> =
DEFAULT_QIHE_RUN_ARGS.iter().map(|arg| (*arg).to_string()).collect(),
Expand All @@ -220,6 +222,25 @@ impl UserConfig {
}
.with_fresh_revision()
}

pub(crate) fn qihe(&self) -> QiheConfig {
let command = Some(self.qihe_command.trim())
.filter(|cmd| !cmd.is_empty())
.unwrap_or(DEFAULT_QIHE_COMMAND)
.to_string();

let run_args =
Some(&self.qihe_runArgs).filter(|args| !args.is_empty()).cloned().unwrap_or_else(
|| DEFAULT_QIHE_RUN_ARGS.iter().map(|arg| (*arg).to_string()).collect(),
);

QiheConfig {
command,
auto_configure_args_from_manifest: self.qihe_autoConfigureArgsFromManifest,
compile_args: self.qihe_compileArgs.clone(),
run_args,
}
}
}

impl DiagnosticRuleUserConfig {
Expand Down Expand Up @@ -322,19 +343,7 @@ impl Config {
}

pub(crate) fn qihe(&self) -> QiheConfig {
let command = Some(self.user_config.qihe_command.trim())
.filter(|cmd| !cmd.is_empty())
.unwrap_or(DEFAULT_QIHE_COMMAND)
.to_string();

let run_args = Some(&self.user_config.qihe_runArgs)
.filter(|args| !args.is_empty())
.cloned()
.unwrap_or_else(|| {
DEFAULT_QIHE_RUN_ARGS.iter().map(|arg| (*arg).to_string()).collect()
});

QiheConfig { command, compile_args: self.user_config.qihe_compileArgs.clone(), run_args }
self.user_config.qihe()
}
}

Expand Down Expand Up @@ -372,3 +381,22 @@ fn parses_nested_diagnostics_config() {
assert_eq!(config.slang.warnings, ["default", "no-unused"]);
assert_eq!(config.slang.rules.len(), 2);
}

#[test]
fn parses_qihe_manifest_arg_configuration() {
let json = serde_json::json!({
"qihe": {
"autoConfigureArgsFromManifest": false,
"compileArgs": ["--mode", "sv2017", "--", "-I", "vendor/include"],
"runArgs": ["-g", "std", "--foo"],
}
});
let mut errors = vec![];
let user_cfg = UserConfig::from_json(json, &mut errors);
assert!(errors.is_empty(), "{errors:?}");

let qihe = user_cfg.qihe();
assert!(!qihe.auto_configure_args_from_manifest);
assert_eq!(qihe.compile_args, ["--mode", "sv2017", "--", "-I", "vendor/include"]);
assert_eq!(qihe.run_args, ["-g", "std", "--foo"]);
}
108 changes: 90 additions & 18 deletions src/global_state/qihe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ fn run_qihe_request(
run_qihe_commands(&qihe_config, &cwd, &compile_input, &ir_path, &storage_root, i18n, log_sink)?;

let diagnostics = load_latest_diagnostics(&storage_root, i18n)?;
let resolution_base = if compile_input.project_mode {
let resolution_base = if compile_input.uses_manifest() {
cwd.as_path()
} else {
active_path
Expand All @@ -289,8 +289,20 @@ fn qihe_working_directory(params_cwd: Option<PathBuf>, root_path: &AbsPath) -> P
#[derive(Debug, Clone, PartialEq, Eq)]
struct QiheCompileInput {
files: Vec<PathBuf>,
slang_args: Vec<String>,
project_mode: bool,
manifest_slang_args: Vec<String>,
source: QiheCompileInputSource,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum QiheCompileInputSource {
SingleFile,
Manifest,
}

impl QiheCompileInput {
fn uses_manifest(&self) -> bool {
matches!(self.source, QiheCompileInputSource::Manifest)
}
}

fn qihe_compile_input(
Expand Down Expand Up @@ -319,8 +331,8 @@ fn qihe_compile_input(
fn single_file_qihe_compile_input(active_path: &AbsPath) -> QiheCompileInput {
QiheCompileInput {
files: vec![active_path.to_path_buf().into()],
slang_args: Vec::new(),
project_mode: false,
manifest_slang_args: Vec::new(),
source: QiheCompileInputSource::SingleFile,
}
}

Expand Down Expand Up @@ -349,7 +361,11 @@ fn qihe_compile_input_from_plan(
slang_args.push(format!("-D{define}"));
}

QiheCompileInput { files, slang_args, project_mode: true }
QiheCompileInput {
files,
manifest_slang_args: slang_args,
source: QiheCompileInputSource::Manifest,
}
}

fn qihe_run_paths(active_path: &AbsPath) -> Result<(PathBuf, PathBuf)> {
Expand Down Expand Up @@ -397,14 +413,19 @@ fn prepare_qihe_compile_command(
) {
let (qihe_args, user_slang_args) = split_compile_args(&qihe_config.compile_args);
command.args(&qihe_args);
if compile_input.project_mode && !has_compile_mode(&qihe_args) {
let auto_configure_manifest_args =
qihe_config.auto_configure_args_from_manifest && compile_input.uses_manifest();
if auto_configure_manifest_args && !has_compile_mode(&qihe_args) {
command.args(["--mode", "sv"]);
}
command.args(&compile_input.files).arg("-o").arg(ir_path);

let has_slang_args = !user_slang_args.is_empty() || !compile_input.slang_args.is_empty();
let manifest_slang_args = auto_configure_manifest_args
.then_some(compile_input.manifest_slang_args.as_slice())
.unwrap_or(&[]);
let has_slang_args = !user_slang_args.is_empty() || !manifest_slang_args.is_empty();
if has_slang_args {
command.arg("--").args(&user_slang_args).args(&compile_input.slang_args);
command.arg("--").args(&user_slang_args).args(manifest_slang_args);
}
}

Expand Down Expand Up @@ -782,9 +803,10 @@ mod tests {
use utils::paths::AbsPathBuf;

use super::{
QiheCompileInput, QiheLogSink, command_line, has_compile_mode, join_command_output,
parse_source_loc, prepare_qihe_compile_command, qihe_compile_input_from_plan,
qihe_working_directory, split_compile_args, stream_command_output, strip_ansi,
QiheCompileInput, QiheCompileInputSource, QiheLogSink, command_line, has_compile_mode,
join_command_output, parse_source_loc, prepare_qihe_compile_command,
qihe_compile_input_from_plan, qihe_working_directory, split_compile_args,
stream_command_output, strip_ansi,
};
use crate::{
config::user_config::QiheConfig,
Expand Down Expand Up @@ -889,19 +911,20 @@ mod tests {
fn project_compile_command_synthesizes_sv_mode_and_slang_args() {
let config = QiheConfig {
command: "qihe".to_owned(),
auto_configure_args_from_manifest: true,
compile_args: vec!["--flag".to_owned(), "--".to_owned(), "--lint".to_owned()],
run_args: Vec::new(),
};
let input = QiheCompileInput {
files: vec![PathBuf::from("/repo/rtl/a.sv"), PathBuf::from("/repo/rtl/b.sv")],
slang_args: vec![
manifest_slang_args: vec![
"--top".to_owned(),
"top".to_owned(),
"-I".to_owned(),
"/repo/include".to_owned(),
"-DDEBUG".to_owned(),
],
project_mode: true,
source: QiheCompileInputSource::Manifest,
};
let mut command = Command::new("qihe");

Expand Down Expand Up @@ -934,17 +957,66 @@ mod tests {
);
}

#[test]
fn project_compile_command_can_disable_manifest_args() {
let config = QiheConfig {
command: "qihe".to_owned(),
auto_configure_args_from_manifest: false,
compile_args: vec![
"--mode".to_owned(),
"custom".to_owned(),
"--".to_owned(),
"--lint".to_owned(),
],
run_args: Vec::new(),
};
let input = QiheCompileInput {
files: vec![PathBuf::from("/repo/rtl/a.sv"), PathBuf::from("/repo/rtl/b.sv")],
manifest_slang_args: vec![
"--top".to_owned(),
"top".to_owned(),
"-I".to_owned(),
"/repo/include".to_owned(),
"-DDEBUG".to_owned(),
],
source: QiheCompileInputSource::Manifest,
};
let mut command = Command::new("qihe");

prepare_qihe_compile_command(
&mut command,
&config,
&input,
PathBuf::from("/tmp/in.qh").as_path(),
);

assert_eq!(
command_args(&command),
[
"--mode",
"custom",
"/repo/rtl/a.sv",
"/repo/rtl/b.sv",
"-o",
"/tmp/in.qh",
"--",
"--lint",
]
);
}

#[test]
fn single_file_compile_command_does_not_force_sv_mode() {
let config = QiheConfig {
command: "qihe".to_owned(),
auto_configure_args_from_manifest: true,
compile_args: Vec::new(),
run_args: Vec::new(),
};
let input = QiheCompileInput {
files: vec![PathBuf::from("/repo/top.sv")],
slang_args: Vec::new(),
project_mode: false,
manifest_slang_args: Vec::new(),
source: QiheCompileInputSource::SingleFile,
};
let mut command = Command::new("qihe");

Expand Down Expand Up @@ -973,8 +1045,8 @@ mod tests {
input,
QiheCompileInput {
files: vec![active_path.into()],
slang_args: Vec::new(),
project_mode: false,
manifest_slang_args: Vec::new(),
source: QiheCompileInputSource::SingleFile,
}
);
}
Expand Down
Loading