Skip to content

Commit 62a57d0

Browse files
authored
feat(vscode): allow disabling manifest-derived Qihe args (#113)
2 parents f4c1e1c + 49f6ea7 commit 62a57d0

7 files changed

Lines changed: 141 additions & 31 deletions

File tree

editors/vscode/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@
127127
"default": "qihe",
128128
"description": "%configuration.qihe.command.description%"
129129
},
130+
"vizsla.qihe.autoConfigureArgsFromManifest": {
131+
"type": "boolean",
132+
"default": true,
133+
"description": "%configuration.qihe.autoConfigureArgsFromManifest.description%"
134+
},
130135
"vizsla.qihe.compileArgs": {
131136
"type": "array",
132137
"items": {

editors/vscode/package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"configuration.server.cwd.description": "Working directory for the Vizsla language server process. Defaults to the first workspace folder.",
77
"configuration.server.additionalArgs.description": "Additional arguments appended when launching the Vizsla language server.",
88
"configuration.qihe.command.description": "Command used to invoke Qihe. It must be available in the environment PATH seen by VS Code.",
9+
"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.",
910
"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`.",
1011
"configuration.qihe.runArgs.description": "Arguments inserted after `qihe run` when the Qihe analysis button is used.",
1112
"configuration.files.excludeDirs.markdownDescription": "Workspace-relative directories ignored by Vizsla. Globs are not supported; add matching patterns to VS Code `files.watcherExclude` if needed.",

editors/vscode/package.nls.zh-cn.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"configuration.server.cwd.description": "Vizsla 语言服务器进程的工作目录。默认使用第一个工作区文件夹。",
77
"configuration.server.additionalArgs.description": "启动 Vizsla 语言服务器时追加的额外参数。",
88
"configuration.qihe.command.description": "用于调用 Qihe 的命令。它必须在 VS Code 可见的环境 PATH 中可用。",
9+
"configuration.qihe.autoConfigureArgsFromManifest.description": "根据 Vizsla 项目配置文件自动添加 Qihe 编译模式和转发给 slang 的选项。关闭后可通过 Qihe 编译和运行参数手动提供这些选项。",
910
"configuration.qihe.compileArgs.description": "插入到 `qihe compile` 之后的参数。可用于选择编译模式,或转发 `slang` 选项,例如 `--mode sv -- -I include`。",
1011
"configuration.qihe.runArgs.description": "使用 Qihe 分析按钮时,插入到 `qihe run` 之后的参数。",
1112
"configuration.files.excludeDirs.markdownDescription": "Vizsla 忽略的工作区相对目录。不支持 glob;如需匹配模式,请添加到 VS Code `files.watcherExclude`。",

editors/vscode/src/profiling.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,8 @@ function readVizslaInitializationOptions(): Record<string, unknown> {
383383
},
384384
signature_help_params_only: config.get('signature.help.params.only') ?? false,
385385
qihe_command: config.get('qihe.command') ?? 'qihe',
386+
qihe_autoConfigureArgsFromManifest:
387+
config.get('qihe.autoConfigureArgsFromManifest') ?? true,
386388
qihe_compileArgs: config.get('qihe.compileArgs') ?? [],
387389
qihe_runArgs: config.get('qihe.runArgs') ?? ['-g', 'std'],
388390
};

editors/vscode/test/configuration.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ test('contributes settings for the complete Vizsla user configuration surface',
8383
'vizsla.server.cwd',
8484
'vizsla.server.additionalArgs',
8585
'vizsla.qihe.command',
86+
'vizsla.qihe.autoConfigureArgsFromManifest',
8687
'vizsla.qihe.compileArgs',
8788
'vizsla.qihe.runArgs',
8889
'vizsla.files.excludeDirs',

src/config/user_config.rs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ fn default_true() -> bool {
124124
#[derive(Debug, Clone, PartialEq, Eq)]
125125
pub(crate) struct QiheConfig {
126126
pub(crate) command: String,
127+
pub(crate) auto_configure_args_from_manifest: bool,
127128
pub(crate) compile_args: Vec<String>,
128129
pub(crate) run_args: Vec<String>,
129130
}
@@ -194,6 +195,7 @@ config_data! {
194195
signature_help_params_only: bool = false,
195196

196197
qihe_command: String = DEFAULT_QIHE_COMMAND.to_string(),
198+
qihe_autoConfigureArgsFromManifest: bool = true,
197199
qihe_compileArgs: Vec<String> = vec![],
198200
qihe_runArgs: Vec<String> =
199201
DEFAULT_QIHE_RUN_ARGS.iter().map(|arg| (*arg).to_string()).collect(),
@@ -220,6 +222,25 @@ impl UserConfig {
220222
}
221223
.with_fresh_revision()
222224
}
225+
226+
pub(crate) fn qihe(&self) -> QiheConfig {
227+
let command = Some(self.qihe_command.trim())
228+
.filter(|cmd| !cmd.is_empty())
229+
.unwrap_or(DEFAULT_QIHE_COMMAND)
230+
.to_string();
231+
232+
let run_args =
233+
Some(&self.qihe_runArgs).filter(|args| !args.is_empty()).cloned().unwrap_or_else(
234+
|| DEFAULT_QIHE_RUN_ARGS.iter().map(|arg| (*arg).to_string()).collect(),
235+
);
236+
237+
QiheConfig {
238+
command,
239+
auto_configure_args_from_manifest: self.qihe_autoConfigureArgsFromManifest,
240+
compile_args: self.qihe_compileArgs.clone(),
241+
run_args,
242+
}
243+
}
223244
}
224245

225246
impl DiagnosticRuleUserConfig {
@@ -322,19 +343,7 @@ impl Config {
322343
}
323344

324345
pub(crate) fn qihe(&self) -> QiheConfig {
325-
let command = Some(self.user_config.qihe_command.trim())
326-
.filter(|cmd| !cmd.is_empty())
327-
.unwrap_or(DEFAULT_QIHE_COMMAND)
328-
.to_string();
329-
330-
let run_args = Some(&self.user_config.qihe_runArgs)
331-
.filter(|args| !args.is_empty())
332-
.cloned()
333-
.unwrap_or_else(|| {
334-
DEFAULT_QIHE_RUN_ARGS.iter().map(|arg| (*arg).to_string()).collect()
335-
});
336-
337-
QiheConfig { command, compile_args: self.user_config.qihe_compileArgs.clone(), run_args }
346+
self.user_config.qihe()
338347
}
339348
}
340349

@@ -372,3 +381,22 @@ fn parses_nested_diagnostics_config() {
372381
assert_eq!(config.slang.warnings, ["default", "no-unused"]);
373382
assert_eq!(config.slang.rules.len(), 2);
374383
}
384+
385+
#[test]
386+
fn parses_qihe_manifest_arg_configuration() {
387+
let json = serde_json::json!({
388+
"qihe": {
389+
"autoConfigureArgsFromManifest": false,
390+
"compileArgs": ["--mode", "sv2017", "--", "-I", "vendor/include"],
391+
"runArgs": ["-g", "std", "--foo"],
392+
}
393+
});
394+
let mut errors = vec![];
395+
let user_cfg = UserConfig::from_json(json, &mut errors);
396+
assert!(errors.is_empty(), "{errors:?}");
397+
398+
let qihe = user_cfg.qihe();
399+
assert!(!qihe.auto_configure_args_from_manifest);
400+
assert_eq!(qihe.compile_args, ["--mode", "sv2017", "--", "-I", "vendor/include"]);
401+
assert_eq!(qihe.run_args, ["-g", "std", "--foo"]);
402+
}

src/global_state/qihe.rs

Lines changed: 90 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ fn run_qihe_request(
266266
run_qihe_commands(&qihe_config, &cwd, &compile_input, &ir_path, &storage_root, i18n, log_sink)?;
267267

268268
let diagnostics = load_latest_diagnostics(&storage_root, i18n)?;
269-
let resolution_base = if compile_input.project_mode {
269+
let resolution_base = if compile_input.uses_manifest() {
270270
cwd.as_path()
271271
} else {
272272
active_path
@@ -289,8 +289,20 @@ fn qihe_working_directory(params_cwd: Option<PathBuf>, root_path: &AbsPath) -> P
289289
#[derive(Debug, Clone, PartialEq, Eq)]
290290
struct QiheCompileInput {
291291
files: Vec<PathBuf>,
292-
slang_args: Vec<String>,
293-
project_mode: bool,
292+
manifest_slang_args: Vec<String>,
293+
source: QiheCompileInputSource,
294+
}
295+
296+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
297+
enum QiheCompileInputSource {
298+
SingleFile,
299+
Manifest,
300+
}
301+
302+
impl QiheCompileInput {
303+
fn uses_manifest(&self) -> bool {
304+
matches!(self.source, QiheCompileInputSource::Manifest)
305+
}
294306
}
295307

296308
fn qihe_compile_input(
@@ -319,8 +331,8 @@ fn qihe_compile_input(
319331
fn single_file_qihe_compile_input(active_path: &AbsPath) -> QiheCompileInput {
320332
QiheCompileInput {
321333
files: vec![active_path.to_path_buf().into()],
322-
slang_args: Vec::new(),
323-
project_mode: false,
334+
manifest_slang_args: Vec::new(),
335+
source: QiheCompileInputSource::SingleFile,
324336
}
325337
}
326338

@@ -349,7 +361,11 @@ fn qihe_compile_input_from_plan(
349361
slang_args.push(format!("-D{define}"));
350362
}
351363

352-
QiheCompileInput { files, slang_args, project_mode: true }
364+
QiheCompileInput {
365+
files,
366+
manifest_slang_args: slang_args,
367+
source: QiheCompileInputSource::Manifest,
368+
}
353369
}
354370

355371
fn qihe_run_paths(active_path: &AbsPath) -> Result<(PathBuf, PathBuf)> {
@@ -397,14 +413,19 @@ fn prepare_qihe_compile_command(
397413
) {
398414
let (qihe_args, user_slang_args) = split_compile_args(&qihe_config.compile_args);
399415
command.args(&qihe_args);
400-
if compile_input.project_mode && !has_compile_mode(&qihe_args) {
416+
let auto_configure_manifest_args =
417+
qihe_config.auto_configure_args_from_manifest && compile_input.uses_manifest();
418+
if auto_configure_manifest_args && !has_compile_mode(&qihe_args) {
401419
command.args(["--mode", "sv"]);
402420
}
403421
command.args(&compile_input.files).arg("-o").arg(ir_path);
404422

405-
let has_slang_args = !user_slang_args.is_empty() || !compile_input.slang_args.is_empty();
423+
let manifest_slang_args = auto_configure_manifest_args
424+
.then_some(compile_input.manifest_slang_args.as_slice())
425+
.unwrap_or(&[]);
426+
let has_slang_args = !user_slang_args.is_empty() || !manifest_slang_args.is_empty();
406427
if has_slang_args {
407-
command.arg("--").args(&user_slang_args).args(&compile_input.slang_args);
428+
command.arg("--").args(&user_slang_args).args(manifest_slang_args);
408429
}
409430
}
410431

@@ -782,9 +803,10 @@ mod tests {
782803
use utils::paths::AbsPathBuf;
783804

784805
use super::{
785-
QiheCompileInput, QiheLogSink, command_line, has_compile_mode, join_command_output,
786-
parse_source_loc, prepare_qihe_compile_command, qihe_compile_input_from_plan,
787-
qihe_working_directory, split_compile_args, stream_command_output, strip_ansi,
806+
QiheCompileInput, QiheCompileInputSource, QiheLogSink, command_line, has_compile_mode,
807+
join_command_output, parse_source_loc, prepare_qihe_compile_command,
808+
qihe_compile_input_from_plan, qihe_working_directory, split_compile_args,
809+
stream_command_output, strip_ansi,
788810
};
789811
use crate::{
790812
config::user_config::QiheConfig,
@@ -889,19 +911,20 @@ mod tests {
889911
fn project_compile_command_synthesizes_sv_mode_and_slang_args() {
890912
let config = QiheConfig {
891913
command: "qihe".to_owned(),
914+
auto_configure_args_from_manifest: true,
892915
compile_args: vec!["--flag".to_owned(), "--".to_owned(), "--lint".to_owned()],
893916
run_args: Vec::new(),
894917
};
895918
let input = QiheCompileInput {
896919
files: vec![PathBuf::from("/repo/rtl/a.sv"), PathBuf::from("/repo/rtl/b.sv")],
897-
slang_args: vec![
920+
manifest_slang_args: vec![
898921
"--top".to_owned(),
899922
"top".to_owned(),
900923
"-I".to_owned(),
901924
"/repo/include".to_owned(),
902925
"-DDEBUG".to_owned(),
903926
],
904-
project_mode: true,
927+
source: QiheCompileInputSource::Manifest,
905928
};
906929
let mut command = Command::new("qihe");
907930

@@ -934,17 +957,66 @@ mod tests {
934957
);
935958
}
936959

960+
#[test]
961+
fn project_compile_command_can_disable_manifest_args() {
962+
let config = QiheConfig {
963+
command: "qihe".to_owned(),
964+
auto_configure_args_from_manifest: false,
965+
compile_args: vec![
966+
"--mode".to_owned(),
967+
"custom".to_owned(),
968+
"--".to_owned(),
969+
"--lint".to_owned(),
970+
],
971+
run_args: Vec::new(),
972+
};
973+
let input = QiheCompileInput {
974+
files: vec![PathBuf::from("/repo/rtl/a.sv"), PathBuf::from("/repo/rtl/b.sv")],
975+
manifest_slang_args: vec![
976+
"--top".to_owned(),
977+
"top".to_owned(),
978+
"-I".to_owned(),
979+
"/repo/include".to_owned(),
980+
"-DDEBUG".to_owned(),
981+
],
982+
source: QiheCompileInputSource::Manifest,
983+
};
984+
let mut command = Command::new("qihe");
985+
986+
prepare_qihe_compile_command(
987+
&mut command,
988+
&config,
989+
&input,
990+
PathBuf::from("/tmp/in.qh").as_path(),
991+
);
992+
993+
assert_eq!(
994+
command_args(&command),
995+
[
996+
"--mode",
997+
"custom",
998+
"/repo/rtl/a.sv",
999+
"/repo/rtl/b.sv",
1000+
"-o",
1001+
"/tmp/in.qh",
1002+
"--",
1003+
"--lint",
1004+
]
1005+
);
1006+
}
1007+
9371008
#[test]
9381009
fn single_file_compile_command_does_not_force_sv_mode() {
9391010
let config = QiheConfig {
9401011
command: "qihe".to_owned(),
1012+
auto_configure_args_from_manifest: true,
9411013
compile_args: Vec::new(),
9421014
run_args: Vec::new(),
9431015
};
9441016
let input = QiheCompileInput {
9451017
files: vec![PathBuf::from("/repo/top.sv")],
946-
slang_args: Vec::new(),
947-
project_mode: false,
1018+
manifest_slang_args: Vec::new(),
1019+
source: QiheCompileInputSource::SingleFile,
9481020
};
9491021
let mut command = Command::new("qihe");
9501022

@@ -973,8 +1045,8 @@ mod tests {
9731045
input,
9741046
QiheCompileInput {
9751047
files: vec![active_path.into()],
976-
slang_args: Vec::new(),
977-
project_mode: false,
1048+
manifest_slang_args: Vec::new(),
1049+
source: QiheCompileInputSource::SingleFile,
9781050
}
9791051
);
9801052
}

0 commit comments

Comments
 (0)