Skip to content

Commit fbc61e8

Browse files
committed
Add spec mode for openqasm compilation.
1 parent 33c0406 commit fbc61e8

File tree

9 files changed

+107
-28
lines changed

9 files changed

+107
-28
lines changed

source/language_service/src/code_lens.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ pub(crate) fn get_code_lenses(
2525
return vec![]; // entrypoint actions don't work in notebooks
2626
}
2727

28+
if matches!(
29+
compilation.kind,
30+
CompilationKind::OpenQASM {
31+
spec_mode: true,
32+
..
33+
}
34+
) {
35+
return vec![]; // entrypoint actions don't work with OpenQASM in spec mode
36+
}
37+
2838
if !compilation.project_errors.is_empty()
2939
|| compilation
3040
.compile_errors

source/language_service/src/compilation.rs

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use log::trace;
55
use qsc::{
66
CompileUnit, LanguageFeatures, PackageStore, PackageType, PassContext, SourceMap, Span, ast,
7-
compile,
7+
compile::{self, package_store_with_stdlib},
88
display::Lookup,
99
error::WithSource,
1010
hir::{self, PackageId},
@@ -63,6 +63,7 @@ pub(crate) enum CompilationKind {
6363
sources: Vec<(Arc<str>, Arc<str>)>,
6464
/// a human-readable name for the package (not a unique URI -- meant to be read by humans)
6565
friendly_name: Arc<str>,
66+
spec_mode: bool,
6667
},
6768
}
6869

@@ -255,6 +256,7 @@ impl Compilation {
255256
pub(crate) fn new_qasm(
256257
package_type: PackageType,
257258
target_profile: Profile,
259+
openqasm_spec_mode: bool,
258260
sources: Vec<(Arc<str>, Arc<str>)>,
259261
project_errors: Vec<project::Error>,
260262
friendly_name: &Arc<str>,
@@ -269,28 +271,53 @@ impl Compilation {
269271
None,
270272
);
271273
let res = qsc::qasm::semantic::parse_sources(&sources);
272-
let unit = compile_to_qsharp_ast_with_config(res, config);
273-
let CompileRawQasmResult(store, source_package_id, dependencies, _sig, mut compile_errors) =
274-
qsc::qasm::compile_openqasm(unit, package_type, capabilities);
275-
276-
let compile_unit = store
277-
.get(source_package_id)
278-
.expect("expected to find user package");
274+
let (compile_errors, store, source_package_id, dependencies) = if openqasm_spec_mode {
275+
// these aren't really used, just to satisfy the API for now.
276+
let (stdid, store) = package_store_with_stdlib(capabilities);
277+
let dependencies = vec![(PackageId::CORE, None), (stdid, None)];
278+
// We have OpenQASM errors, convert them to the same type as as the Q#
279+
// compilation errors
280+
let mut compile_errors = Vec::with_capacity(res.errors.len());
281+
for error in res.errors {
282+
let err = WithSource::from_map(
283+
&res.source_map,
284+
qsc::compile::ErrorKind::OpenQasm(error.into_error()),
285+
);
286+
compile_errors.push(err);
287+
}
279288

280-
run_fir_passes(
281-
&mut compile_errors,
282-
target_profile,
283-
&store,
284-
source_package_id,
285-
compile_unit,
286-
);
289+
(compile_errors, store, stdid, dependencies)
290+
} else {
291+
let unit = compile_to_qsharp_ast_with_config(res, config);
292+
let CompileRawQasmResult(
293+
store,
294+
source_package_id,
295+
dependencies,
296+
_sig,
297+
mut compile_errors,
298+
) = qsc::qasm::compile_openqasm(unit, package_type, capabilities);
299+
300+
let compile_unit = store
301+
.get(source_package_id)
302+
.expect("expected to find user package");
303+
304+
run_fir_passes(
305+
&mut compile_errors,
306+
target_profile,
307+
&store,
308+
source_package_id,
309+
compile_unit,
310+
);
311+
(compile_errors, store, source_package_id, dependencies)
312+
};
287313

288314
Self {
289315
package_store: store,
290316
user_package_id: source_package_id,
291317
kind: CompilationKind::OpenQASM {
292318
sources,
293319
friendly_name: friendly_name.clone(),
320+
spec_mode: openqasm_spec_mode,
294321
},
295322
compile_errors,
296323
project_errors,
@@ -392,6 +419,7 @@ impl Compilation {
392419
target_profile: Profile,
393420
language_features: LanguageFeatures,
394421
lints_config: &[LintOrGroupConfig],
422+
openqasm_spec_mode: bool,
395423
) {
396424
let new = match self.kind {
397425
CompilationKind::OpenProject {
@@ -424,9 +452,11 @@ impl Compilation {
424452
CompilationKind::OpenQASM {
425453
ref sources,
426454
ref friendly_name,
455+
..
427456
} => Self::new_qasm(
428457
package_type,
429458
target_profile,
459+
openqasm_spec_mode,
430460
sources.clone(),
431461
Vec::new(), // project errors will stay the same
432462
friendly_name,

source/language_service/src/completion/tests/openqasm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ fn compile_project_with_markers_cursor_optional(
2222
Compilation::new_qasm(
2323
PackageType::Lib,
2424
qsc::target::Profile::Unrestricted,
25+
false,
2526
sources,
2627
vec![],
2728
&Arc::from("test project"),

source/language_service/src/protocol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub struct WorkspaceConfigurationUpdate {
1616
pub package_type: Option<PackageType>,
1717
pub language_features: Option<LanguageFeatures>,
1818
pub lints_config: Option<Vec<LintOrGroupConfig>>,
19+
pub openqasm_spec_mode: Option<bool>,
1920
pub dev_diagnostics: Option<bool>,
2021
}
2122

source/language_service/src/state.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ struct Configuration {
6767
pub package_type: PackageType,
6868
pub language_features: LanguageFeatures,
6969
pub lints_config: Vec<LintOrGroupConfig>,
70+
pub openqasm_spec_mode: bool,
7071
/// Enables non-user-facing developer diagnostics.
7172
pub dev_diagnostics: bool,
7273
}
@@ -78,6 +79,7 @@ impl Default for Configuration {
7879
package_type: PackageType::Lib,
7980
language_features: LanguageFeatures::default(),
8081
lints_config: Vec::default(),
82+
openqasm_spec_mode: false,
8183
dev_diagnostics: false,
8284
}
8385
}
@@ -89,6 +91,7 @@ pub struct PartialConfiguration {
8991
pub package_type: Option<PackageType>,
9092
pub language_features: Option<LanguageFeatures>,
9193
pub lints_config: Vec<LintOrGroupConfig>,
94+
pub openqasm_spec_mode: Option<bool>,
9295
}
9396

9497
pub(super) struct CompilationStateUpdater<'a> {
@@ -310,6 +313,7 @@ impl<'a> CompilationStateUpdater<'a> {
310313
ProjectType::OpenQASM(sources) => Compilation::new_qasm(
311314
configuration.package_type,
312315
configuration.target_profile,
316+
configuration.openqasm_spec_mode,
313317
sources,
314318
loaded_project.errors,
315319
&loaded_project.name,
@@ -416,6 +420,7 @@ impl<'a> CompilationStateUpdater<'a> {
416420
.manifest
417421
.map(|manifest| manifest.lints)
418422
.unwrap_or_default(),
423+
openqasm_spec_mode: None,
419424
};
420425
let configuration = merge_configurations(&notebook_configuration, &configuration);
421426

@@ -572,6 +577,11 @@ impl<'a> CompilationStateUpdater<'a> {
572577
self.configuration.lints_config = lints_config;
573578
}
574579

580+
if let Some(openqasm_spec_mode) = configuration.openqasm_spec_mode {
581+
need_recompile |= self.configuration.openqasm_spec_mode != openqasm_spec_mode;
582+
self.configuration.openqasm_spec_mode = openqasm_spec_mode;
583+
}
584+
575585
if let Some(dev_diagnostics) = configuration.dev_diagnostics {
576586
need_recompile |= self.configuration.dev_diagnostics != dev_diagnostics;
577587
self.configuration.dev_diagnostics = dev_diagnostics;
@@ -598,6 +608,7 @@ impl<'a> CompilationStateUpdater<'a> {
598608
configuration.target_profile,
599609
configuration.language_features,
600610
&lints_config,
611+
configuration.openqasm_spec_mode,
601612
);
602613
}
603614
});
@@ -767,6 +778,7 @@ fn merge_configurations(
767778
.language_features
768779
.unwrap_or(workspace_scope.language_features),
769780
lints_config: merged_lints,
781+
openqasm_spec_mode: compilation_overrides.openqasm_spec_mode.unwrap_or_default(),
770782
dev_diagnostics: workspace_scope.dev_diagnostics,
771783
}
772784
}

source/vscode/package.json

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
},
1616
"categories": [
1717
"Programming Languages",
18-
"Notebooks"
18+
"Notebooks",
19+
"Debuggers",
20+
"Formatters",
21+
"Linters"
1922
],
2023
"browser": "./out/extension.js",
2124
"virtualWorkspaces": true,
@@ -161,34 +164,39 @@
161164
"type": "boolean",
162165
"default": false,
163166
"description": "Suppress notifications about new QDK updates. If true, you will not be prompted about new features after updates."
167+
},
168+
"qdk.openqasm.enableSpecMode": {
169+
"type": "boolean",
170+
"default": false,
171+
"description": "Only show OpenQASM syntax and semantic errors. This will disable the Q#-specific integration diagnostics and features."
164172
}
165173
}
166174
},
167175
"menus": {
168176
"editor/title/run": [
169177
{
170178
"command": "qsharp-vscode.runProgram",
171-
"when": "resourceLangId == qsharp || resourceLangId == openqasm || resourceLangId == qsharpcircuit",
179+
"when": "(resourceLangId == qsharp || resourceLangId == qsharpcircuit) || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)",
172180
"group": "navigation@1"
173181
},
174182
{
175183
"command": "qsharp-vscode.debugProgram",
176-
"when": "resourceLangId == qsharp || resourceLangId == openqasm || resourceLangId == qsharpcircuit",
184+
"when": "(resourceLangId == qsharp || resourceLangId == qsharpcircuit) || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)",
177185
"group": "navigation@2"
178186
}
179187
],
180188
"commandPalette": [
181189
{
182190
"command": "qsharp-vscode.runProgram",
183-
"when": "resourceLangId == qsharp || resourceLangId == openqasm || resourceLangId == qsharpcircuit"
191+
"when": "(resourceLangId == qsharp || resourceLangId == qsharpcircuit) || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)"
184192
},
185193
{
186194
"command": "qsharp-vscode.debugProgram",
187-
"when": "resourceLangId == qsharp || resourceLangId == openqasm || resourceLangId == qsharpcircuit"
195+
"when": "(resourceLangId == qsharp || resourceLangId == qsharpcircuit) || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)"
188196
},
189197
{
190198
"command": "qsharp-vscode.runEditorContentsWithCircuit",
191-
"when": "resourceLangId == qsharp || resourceLangId == openqasm"
199+
"when": "(resourceLangId == qsharp || resourceLangId == qsharpcircuit) || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)"
192200
},
193201
{
194202
"command": "qsharp-vscode.targetSubmit",
@@ -212,31 +220,31 @@
212220
},
213221
{
214222
"command": "qsharp-vscode.getQir",
215-
"when": "resourceLangId == qsharp || resourceLangId == openqasm"
223+
"when": "(resourceLangId == qsharp || resourceLangId == qsharpcircuit) || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)"
216224
},
217225
{
218226
"command": "qsharp-vscode.showHistogram",
219-
"when": "resourceLangId == qsharp || resourceLangId == openqasm"
227+
"when": "(resourceLangId == qsharp || resourceLangId == qsharpcircuit) || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)"
220228
},
221229
{
222230
"command": "qsharp-vscode.showRe",
223-
"when": "resourceLangId == qsharp || resourceLangId == openqasm"
231+
"when": "(resourceLangId == qsharp || resourceLangId == qsharpcircuit) || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)"
224232
},
225233
{
226234
"command": "qsharp-vscode.showHelp",
227235
"when": "resourceLangId == qsharp"
228236
},
229237
{
230238
"command": "qsharp-vscode.showCircuit",
231-
"when": "resourceLangId == qsharp || resourceLangId == openqasm"
239+
"when": "(resourceLangId == qsharp || resourceLangId == qsharpcircuit) || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)"
232240
},
233241
{
234242
"command": "qsharp-vscode.showDocumentation",
235243
"when": "resourceLangId == qsharp"
236244
},
237245
{
238246
"command": "qsharp-vscode.setTargetProfile",
239-
"when": "resourceLangId == qsharp || resourceLangId == openqasm"
247+
"when": "resourceLangId == qsharp || (resourceLangId == openqasm && !config.qdk.openqasm.enableSpecMode)"
240248
},
241249
{
242250
"command": "qsharp-vscode.webOpener",

source/vscode/src/config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,9 @@ export function getShowDevDiagnostics(): boolean {
6969
.getConfiguration("Q#")
7070
.get<boolean>("dev.showDevDiagnostics", false);
7171
}
72+
73+
export function getOpenQasmEnableSpecMode(): boolean {
74+
return vscode.workspace
75+
.getConfiguration("qdk")
76+
.get<boolean>("openqasm.enableSpecMode", false);
77+
}

source/vscode/src/language-service/activate.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ import {
1414
openqasmLanguageId,
1515
qsharpLanguageId,
1616
} from "../common.js";
17-
import { getTarget, getShowDevDiagnostics } from "../config.js";
17+
import {
18+
getTarget,
19+
getShowDevDiagnostics,
20+
getOpenQasmEnableSpecMode,
21+
} from "../config.js";
1822
import {
1923
fetchGithubRaw,
2024
findManifestDirectory,
@@ -317,7 +321,8 @@ function registerConfigurationChangeHandlers(
317321
return vscode.workspace.onDidChangeConfiguration((event) => {
318322
if (
319323
event.affectsConfiguration("Q#.qir.targetProfile") ||
320-
event.affectsConfiguration("Q#.dev.showDevDiagnostics")
324+
event.affectsConfiguration("Q#.dev.showDevDiagnostics") ||
325+
event.affectsConfiguration("qdk.openqasm.enableSpecMode")
321326
) {
322327
updateLanguageServiceConfiguration(languageService);
323328
}
@@ -329,6 +334,7 @@ async function updateLanguageServiceConfiguration(
329334
) {
330335
const targetProfile = getTarget();
331336
const showDevDiagnostics = getShowDevDiagnostics();
337+
const openqasmSpecMode = getOpenQasmEnableSpecMode();
332338

333339
switch (targetProfile) {
334340
case "base":
@@ -341,11 +347,13 @@ async function updateLanguageServiceConfiguration(
341347
}
342348
log.debug("Target profile set to: " + targetProfile);
343349
log.debug("Show dev diagnostics set to: " + showDevDiagnostics);
350+
log.debug("OpenQASM spec mode set to: " + openqasmSpecMode);
344351

345352
// Update all configuration settings
346353
languageService.updateConfiguration({
347354
targetProfile: targetProfile,
348355
devDiagnostics: showDevDiagnostics,
356+
openqasmSpecMode: openqasmSpecMode,
349357
lints: [{ lint: "needlessOperation", level: "warn" }],
350358
});
351359
}

source/wasm/src/language_service.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ impl LanguageService {
124124
.languageFeatures
125125
.map(|features| features.iter().collect::<LanguageFeatures>()),
126126
lints_config: config.lints,
127+
openqasm_spec_mode: config.openqasmSpecMode,
127128
dev_diagnostics: config.devDiagnostics,
128129
});
129130
}
@@ -382,13 +383,15 @@ serializable_type! {
382383
pub languageFeatures: Option<Vec<String>>,
383384
pub lints: Option<Vec<LintOrGroupConfig>>,
384385
pub devDiagnostics: Option<bool>,
386+
pub openqasmSpecMode: Option<bool>,
385387
},
386388
r#"export interface IWorkspaceConfiguration {
387389
targetProfile?: TargetProfile;
388390
packageType?: "exe" | "lib";
389391
languageFeatures?: LanguageFeatures[];
390392
lints?: ({ lint: string; level: string } | { group: string; level: string })[];
391393
devDiagnostics?: boolean;
394+
openqasmSpecMode?: boolean;
392395
}"#,
393396
IWorkspaceConfiguration
394397
}

0 commit comments

Comments
 (0)