1
1
// Copyright (c) Microsoft Corporation.
2
2
// Licensed under the MIT License.
3
3
4
- import { type Circuit as CircuitData } from "@microsoft/quantum-viz.js/lib/circuit.js" ;
4
+ import { type Circuit as CircuitData } from "@microsoft/quantum-viz.js/lib" ;
5
+ import { escapeHtml } from "markdown-it/lib/common/utils" ;
5
6
import {
6
7
IOperationInfo ,
7
8
IRange ,
@@ -52,7 +53,9 @@ export async function showCircuitCommand(
52
53
log . info ( "terminating circuit worker due to timeout" ) ;
53
54
worker . terminate ( ) ;
54
55
} , compilerRunTimeoutMs ) ;
55
- const sources = await loadProject ( editor . document . uri ) ;
56
+
57
+ const docUri = editor . document . uri ;
58
+ const sources = await loadProject ( docUri ) ;
56
59
const targetProfile = getTarget ( ) ;
57
60
58
61
try {
@@ -63,10 +66,9 @@ export async function showCircuitCommand(
63
66
64
67
updateCircuitPanel (
65
68
targetProfile ,
66
- editor . document . uri . path ,
67
- circuit ,
69
+ docUri . path ,
68
70
true , // reveal
69
- operation ,
71
+ { circuit , operation } ,
70
72
) ;
71
73
72
74
sendTelemetryEvent ( EventType . CircuitEnd , {
@@ -81,7 +83,7 @@ export async function showCircuitCommand(
81
83
typeof e === "string" ? JSON . parse ( e ) : undefined ;
82
84
let errorHtml = "There was an error generating the circuit." ;
83
85
if ( errors ) {
84
- errorHtml = errorsToHtml ( errors ) ;
86
+ errorHtml = errorsToHtml ( errors , docUri ) ;
85
87
}
86
88
87
89
if ( ! timeout ) {
@@ -94,46 +96,16 @@ export async function showCircuitCommand(
94
96
95
97
updateCircuitPanel (
96
98
targetProfile ,
97
- editor . document . uri . path ,
98
- errorHtml ,
99
+ docUri . path ,
99
100
false , // reveal
100
- operation ,
101
+ { errorHtml , operation } ,
101
102
) ;
102
103
} finally {
103
104
log . info ( "terminating circuit worker" ) ;
104
105
worker . terminate ( ) ;
105
106
}
106
107
}
107
108
108
- export function updateCircuitPanel (
109
- targetProfile : string ,
110
- docPath : string ,
111
- circuitOrErrorHtml : CircuitData | string ,
112
- reveal : boolean ,
113
- operation ?: IOperationInfo | undefined ,
114
- ) {
115
- let title ;
116
- let subtitle ;
117
- if ( operation ) {
118
- title = `${ operation . operation } with ${ operation . totalNumQubits } input qubits` ;
119
- subtitle = `Target profile: ${ getTargetFriendlyName ( targetProfile ) } ` ;
120
- } else {
121
- title = basename ( docPath ) || "Circuit" ;
122
- subtitle = `Target profile: ${ getTargetFriendlyName ( targetProfile ) } ` ;
123
- }
124
-
125
- const message = {
126
- command : "circuit" ,
127
- title,
128
- subtitle,
129
- circuit :
130
- typeof circuitOrErrorHtml === "object" ? circuitOrErrorHtml : undefined ,
131
- errorHtml :
132
- typeof circuitOrErrorHtml === "string" ? circuitOrErrorHtml : undefined ,
133
- } ;
134
- sendMessageToPanel ( "circuit" , reveal , message ) ;
135
- }
136
-
137
109
/**
138
110
* Formats an array of compiler/runtime errors into HTML to be presented to the user.
139
111
*
@@ -145,20 +117,37 @@ export function updateCircuitPanel(
145
117
* @returns The HTML formatted errors, to be set as the inner contents of a container element.
146
118
*/
147
119
function errorsToHtml (
148
- errors : [ string , VSDiagnostic , string | undefined ] [ ] ,
149
- ) : string {
120
+ errors : [ string , VSDiagnostic , string ] [ ] ,
121
+ programUri : Uri ,
122
+ ) {
150
123
let errorHtml = "" ;
151
124
for ( const error of errors ) {
152
125
const [ document , diag , rawStack ] = error ;
153
126
154
- const location = documentHtml ( document , diag . range ) ;
155
-
156
- const message = escapeHtml ( `(${ diag . code } ) ${ diag . message } ` ) . replace (
157
- "\n" ,
158
- "<br/><br/>" ,
159
- ) ;
160
-
161
- errorHtml += `<p>${ location } : ${ message } <br/></p>` ;
127
+ if ( diag . code === "Qsc.Eval.ResultComparisonUnsupported" ) {
128
+ const commandUri = Uri . parse (
129
+ `command:qsharp-vscode.runEditorContentsWithCircuit?${ encodeURIComponent ( JSON . stringify ( [ programUri ] ) ) } ` ,
130
+ true ,
131
+ ) ;
132
+ const messageHtml =
133
+ `<p>Synthesizing circuits is unsupported for programs that ` +
134
+ `contain behavior that is conditional on a qubit measurement result, ` +
135
+ `since the resulting circuit may depend on the outcome of the measurement.</p>` +
136
+ `<p>If you would like to generate a circuit for this program, you can ` +
137
+ `<a href="${ commandUri } ">run the program in the simulator and show the resulting circuit</a>, ` +
138
+ `or edit your code to avoid the result comparison indicated by the call stack below.</p>` ;
139
+
140
+ errorHtml += messageHtml ;
141
+ } else {
142
+ const location = documentHtml ( document , diag . range ) ;
143
+
144
+ const message = escapeHtml ( `(${ diag . code } ) ${ diag . message } ` ) . replace (
145
+ "\n" ,
146
+ "<br/><br/>" ,
147
+ ) ;
148
+
149
+ errorHtml += `<p>${ location } : ${ message } <br/></p>` ;
150
+ }
162
151
163
152
if ( rawStack ) {
164
153
const stack = rawStack
@@ -181,6 +170,39 @@ function errorsToHtml(
181
170
return errorHtml ;
182
171
}
183
172
173
+ export function updateCircuitPanel (
174
+ targetProfile : string ,
175
+ docPath : string ,
176
+ reveal : boolean ,
177
+ params : {
178
+ circuit ?: CircuitData ;
179
+ errorHtml ?: string ;
180
+ simulating ?: boolean ;
181
+ operation ?: IOperationInfo | undefined ;
182
+ } ,
183
+ ) {
184
+ const title = params ?. operation
185
+ ? `${ params . operation . operation } with ${ params . operation . totalNumQubits } input qubits`
186
+ : basename ( docPath ) || "Circuit" ;
187
+
188
+ // Trim the Q#: prefix from the target profile name - that's meant for the ui text in the status bar
189
+ const target = `Target profile: ${ getTargetFriendlyName ( targetProfile ) . replace ( "Q#: " , "" ) } ` ;
190
+
191
+ const props = {
192
+ title,
193
+ targetProfile : target ,
194
+ simulating : params ?. simulating || false ,
195
+ circuit : params ?. circuit ,
196
+ errorHtml : params ?. errorHtml ,
197
+ } ;
198
+
199
+ const message = {
200
+ command : "circuit" ,
201
+ props,
202
+ } ;
203
+ sendMessageToPanel ( "circuit" , reveal , message ) ;
204
+ }
205
+
184
206
/**
185
207
* If the input is a URI, turns it into a document open link.
186
208
* Otherwise returns the HTML-escaped input
@@ -218,12 +240,3 @@ function documentHtml(maybeUri: string, range?: IRange) {
218
240
219
241
return location ;
220
242
}
221
-
222
- function escapeHtml ( unsafe : string ) : string {
223
- return unsafe
224
- . replace ( / & / g, "&" )
225
- . replace ( / < / g, "<" )
226
- . replace ( / > / g, ">" )
227
- . replace ( / " / g, """ )
228
- . replace ( / ' / g, "'" ) ;
229
- }
0 commit comments