qsharp-lang 0.1.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +74 -0
  3. package/dist/browser.d.ts +26 -0
  4. package/dist/browser.js +156 -0
  5. package/dist/cancellation.d.ts +10 -0
  6. package/dist/cancellation.js +31 -0
  7. package/dist/compiler/common.d.ts +31 -0
  8. package/dist/compiler/common.js +47 -0
  9. package/dist/compiler/compiler.d.ts +28 -0
  10. package/dist/compiler/compiler.js +62 -0
  11. package/dist/compiler/events.d.ts +54 -0
  12. package/dist/compiler/events.js +92 -0
  13. package/dist/compiler/worker-browser.d.ts +1 -0
  14. package/dist/compiler/worker-browser.js +43 -0
  15. package/dist/compiler/worker-node.d.ts +1 -0
  16. package/dist/compiler/worker-node.js +41 -0
  17. package/dist/compiler/worker-proxy.d.ts +7 -0
  18. package/dist/compiler/worker-proxy.js +16 -0
  19. package/dist/debug-service/debug-service.d.ts +35 -0
  20. package/dist/debug-service/debug-service.js +136 -0
  21. package/dist/debug-service/worker-browser.d.ts +1 -0
  22. package/dist/debug-service/worker-browser.js +32 -0
  23. package/dist/debug-service/worker-node.d.ts +1 -0
  24. package/dist/debug-service/worker-node.js +30 -0
  25. package/dist/debug-service/worker-proxy.d.ts +7 -0
  26. package/dist/debug-service/worker-proxy.js +22 -0
  27. package/dist/katas-content.generated.d.ts +61 -0
  28. package/dist/katas-content.generated.js +2499 -0
  29. package/dist/katas.d.ts +55 -0
  30. package/dist/katas.js +16 -0
  31. package/dist/language-service/language-service.d.ts +48 -0
  32. package/dist/language-service/language-service.js +85 -0
  33. package/dist/language-service/worker-browser.d.ts +1 -0
  34. package/dist/language-service/worker-browser.js +32 -0
  35. package/dist/language-service/worker-node.d.ts +1 -0
  36. package/dist/language-service/worker-node.js +30 -0
  37. package/dist/language-service/worker-proxy.d.ts +6 -0
  38. package/dist/language-service/worker-proxy.js +20 -0
  39. package/dist/log.d.ts +33 -0
  40. package/dist/log.js +92 -0
  41. package/dist/main.d.ts +11 -0
  42. package/dist/main.js +82 -0
  43. package/dist/samples.generated.d.ts +6 -0
  44. package/dist/samples.generated.js +62 -0
  45. package/dist/vsdiagnostic.d.ts +27 -0
  46. package/dist/vsdiagnostic.js +117 -0
  47. package/dist/worker-proxy.d.ts +95 -0
  48. package/dist/worker-proxy.js +226 -0
  49. package/lib/node/qsc_wasm.cjs +1010 -0
  50. package/lib/node/qsc_wasm.d.cts +266 -0
  51. package/lib/node/qsc_wasm_bg.wasm +0 -0
  52. package/lib/web/qsc_wasm.d.ts +328 -0
  53. package/lib/web/qsc_wasm.js +1026 -0
  54. package/lib/web/qsc_wasm_bg.wasm +0 -0
  55. package/package.json +35 -0
@@ -0,0 +1,43 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import * as wasm from "../../lib/web/qsc_wasm.js";
4
+ import { log } from "../log.js";
5
+ import { Compiler } from "./compiler.js";
6
+ import { createCompilerDispatcher } from "./worker-proxy.js";
7
+ let invokeCompiler = null;
8
+ function telemetryHandler(telemetry) {
9
+ self.postMessage({
10
+ messageType: "event",
11
+ type: "telemetry-event",
12
+ detail: telemetry,
13
+ });
14
+ }
15
+ // This export should be assigned to 'self.onmessage' in a WebWorker
16
+ export function messageHandler(e) {
17
+ const data = e.data;
18
+ if (!data.type || typeof data.type !== "string") {
19
+ log.error(`Unrecognized msg: ${data}`);
20
+ return;
21
+ }
22
+ switch (data.type) {
23
+ case "init":
24
+ {
25
+ log.setLogLevel(data.qscLogLevel);
26
+ log.setTelemetryCollector(telemetryHandler);
27
+ wasm.initSync(data.wasmModule);
28
+ // Set up logging and telemetry as soon as possible after instantiating
29
+ wasm.initLogging(log.logWithLevel, log.getLogLevel());
30
+ log.onLevelChanged = (level) => wasm.setLogLevel(level);
31
+ const compiler = new Compiler(wasm);
32
+ invokeCompiler = createCompilerDispatcher(self.postMessage.bind(self), compiler);
33
+ }
34
+ break;
35
+ default:
36
+ if (!invokeCompiler) {
37
+ log.error(`Received message before the compiler was initialized: %o`, data);
38
+ }
39
+ else {
40
+ invokeCompiler(data);
41
+ }
42
+ }
43
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,41 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ // This module supports running the qsharp compiler in a Node.js worker thread. It should be
4
+ // used in a Node.js module in a manner similar to the below to create it with the right log level:
5
+ //
6
+ // const worker = new Worker(join(thisDir,"worker-node.js"), {
7
+ // workerData: {qscLogLevel: log.getLogLevel() }
8
+ // });
9
+ import { isMainThread, parentPort, workerData } from "node:worker_threads";
10
+ import * as wasm from "../../lib/node/qsc_wasm.cjs";
11
+ import { log } from "../log.js";
12
+ import { Compiler } from "./compiler.js";
13
+ import { createCompilerDispatcher } from "./worker-proxy.js";
14
+ if (isMainThread)
15
+ throw "Worker script should be loaded in a Worker thread only";
16
+ if (workerData && typeof workerData.qscLogLevel === "number") {
17
+ log.setLogLevel(workerData.qscLogLevel);
18
+ }
19
+ const port = parentPort; // eslint-disable-line @typescript-eslint/no-non-null-assertion
20
+ const postMessage = port.postMessage.bind(port);
21
+ function telemetryHandler(telemetry) {
22
+ postMessage({
23
+ messageType: "event",
24
+ type: "telemetry-event",
25
+ detail: telemetry,
26
+ });
27
+ }
28
+ // Set up logging and telemetry as soon as possible after instantiating
29
+ log.onLevelChanged = (level) => wasm.setLogLevel(level);
30
+ log.setTelemetryCollector(telemetryHandler);
31
+ wasm.initLogging(log.logWithLevel, log.getLogLevel());
32
+ const compiler = new Compiler(wasm);
33
+ const invokeCompiler = createCompilerDispatcher(postMessage, compiler);
34
+ function messageHandler(data) {
35
+ if (!data.type || typeof data.type !== "string") {
36
+ log.error(`Unrecognized msg: %O"`, data);
37
+ return;
38
+ }
39
+ invokeCompiler(data);
40
+ }
41
+ port.addListener("message", messageHandler);
@@ -0,0 +1,7 @@
1
+ import { EventMessage, RequestMessage, ResponseMessage } from "../worker-proxy.js";
2
+ import { ICompiler } from "./compiler.js";
3
+ import { QscEventData } from "./events.js";
4
+ export declare function createCompilerDispatcher(postMessage: (msg: ResponseMessage<ICompiler> | EventMessage<QscEventData>) => void, service: ICompiler): (req: RequestMessage<ICompiler>) => any;
5
+ export declare function createCompilerProxy(postMessage: (msg: RequestMessage<ICompiler>) => void, terminator: () => void): ICompiler & import("../worker-proxy.js").IServiceProxy & {
6
+ onMsgFromWorker: (msg: ResponseMessage<ICompiler> | EventMessage<QscEventData>) => void;
7
+ };
@@ -0,0 +1,16 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import { createDispatcher, createProxy, } from "../worker-proxy.js";
4
+ const requests = {
5
+ checkCode: "request",
6
+ getHir: "request",
7
+ run: "requestWithProgress",
8
+ checkExerciseSolution: "requestWithProgress",
9
+ };
10
+ const events = ["DumpMachine", "Message", "Result"];
11
+ export function createCompilerDispatcher(postMessage, service) {
12
+ return createDispatcher(postMessage, service, requests, events);
13
+ }
14
+ export function createCompilerProxy(postMessage, terminator) {
15
+ return createProxy(postMessage, terminator, requests);
16
+ }
@@ -0,0 +1,35 @@
1
+ import type { IBreakpointSpan, IStackFrame, IStructStepResult, IVariable, IQuantumState } from "../../lib/node/qsc_wasm.cjs";
2
+ import { IQscEventTarget } from "../compiler/events.js";
3
+ import { IServiceProxy } from "../worker-proxy.js";
4
+ type QscWasm = typeof import("../../lib/node/qsc_wasm.cjs");
5
+ export interface IDebugService {
6
+ loadSource(path: string, source: string, entry: string | undefined): Promise<string>;
7
+ getBreakpoints(path: string): Promise<IBreakpointSpan[]>;
8
+ getLocalVariables(): Promise<Array<IVariable>>;
9
+ captureQuantumState(): Promise<Array<IQuantumState>>;
10
+ getStackFrames(): Promise<IStackFrame[]>;
11
+ evalContinue(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
12
+ evalNext(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
13
+ evalStepIn(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
14
+ evalStepOut(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
15
+ dispose(): Promise<void>;
16
+ }
17
+ export type IDebugServiceWorker = IDebugService & IServiceProxy;
18
+ export declare class QSharpDebugService implements IDebugService {
19
+ private wasm;
20
+ private debugService;
21
+ private code;
22
+ constructor(wasm: QscWasm);
23
+ loadSource(path: string, source: string, entry: string | undefined): Promise<string>;
24
+ getStackFrames(): Promise<IStackFrame[]>;
25
+ evalNext(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
26
+ evalStepIn(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
27
+ evalStepOut(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
28
+ evalContinue(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
29
+ getBreakpoints(path: string): Promise<IBreakpointSpan[]>;
30
+ captureQuantumState(): Promise<Array<IQuantumState>>;
31
+ getLocalVariables(): Promise<Array<IVariable>>;
32
+ dispose(): Promise<void>;
33
+ }
34
+ export declare function onCompilerEvent(msg: string, eventTarget: IQscEventTarget): void;
35
+ export {};
@@ -0,0 +1,136 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import { eventStringToMsg } from "../compiler/common.js";
4
+ import { makeEvent } from "../compiler/events.js";
5
+ import { log } from "../log.js";
6
+ import { mapUtf8UnitsToUtf16Units } from "../vsdiagnostic.js";
7
+ export class QSharpDebugService {
8
+ constructor(wasm) {
9
+ // We need to keep a copy of the code for mapping diagnostics to utf16 offsets
10
+ this.code = {};
11
+ log.info("Constructing a QSharpDebugService instance");
12
+ this.wasm = wasm;
13
+ this.debugService = new wasm.DebugService();
14
+ }
15
+ async loadSource(path, source, entry) {
16
+ this.code[path] = source;
17
+ return this.debugService.load_source(path, source, entry);
18
+ }
19
+ async getStackFrames() {
20
+ const stack_frame_list = this.debugService.get_stack_frames();
21
+ const stack_frames = await Promise.all(stack_frame_list.frames.map(async (frame) => {
22
+ // get any missing sources if possible
23
+ if (!(frame.path in this.code)) {
24
+ const content = await this.wasm.get_library_source_content(frame.path);
25
+ if (content) {
26
+ this.code[frame.path] = content;
27
+ }
28
+ }
29
+ if (frame.path in this.code) {
30
+ const mappedSpan = mapUtf8UnitsToUtf16Units([frame.lo, frame.hi], this.code[frame.path]);
31
+ return {
32
+ ...frame,
33
+ lo: mappedSpan[frame.lo],
34
+ hi: mappedSpan[frame.hi],
35
+ };
36
+ }
37
+ else {
38
+ // We don't have a source file for this frame,
39
+ // and we couldn't load it, so just return it as-is
40
+ return frame;
41
+ }
42
+ }));
43
+ return stack_frames;
44
+ }
45
+ async evalNext(bps, eventHandler) {
46
+ const event_cb = (msg) => onCompilerEvent(msg, eventHandler);
47
+ const ids = new Uint32Array(bps);
48
+ const result = this.debugService.eval_next(event_cb, ids);
49
+ return { id: result.id, value: result.value };
50
+ }
51
+ async evalStepIn(bps, eventHandler) {
52
+ const event_cb = (msg) => onCompilerEvent(msg, eventHandler);
53
+ const ids = new Uint32Array(bps);
54
+ const result = this.debugService.eval_step_in(event_cb, ids);
55
+ return { id: result.id, value: result.value };
56
+ }
57
+ async evalStepOut(bps, eventHandler) {
58
+ const event_cb = (msg) => onCompilerEvent(msg, eventHandler);
59
+ const ids = new Uint32Array(bps);
60
+ const result = this.debugService.eval_step_out(event_cb, ids);
61
+ return { id: result.id, value: result.value };
62
+ }
63
+ async evalContinue(bps, eventHandler) {
64
+ const event_cb = (msg) => onCompilerEvent(msg, eventHandler);
65
+ const ids = new Uint32Array(bps);
66
+ const result = this.debugService.eval_continue(event_cb, ids);
67
+ return { id: result.id, value: result.value };
68
+ }
69
+ async getBreakpoints(path) {
70
+ const breakpoint_list = this.debugService.get_breakpoints(path);
71
+ // Get a map of the Rust source positions to the JavaScript source positions
72
+ const positions = [];
73
+ breakpoint_list.spans.forEach((span) => {
74
+ positions.push(span.lo);
75
+ positions.push(span.hi);
76
+ });
77
+ const positionMap = mapUtf8UnitsToUtf16Units(positions, this.code[path]);
78
+ const breakpoint_spans = breakpoint_list.spans.map((span) => {
79
+ const result = {};
80
+ result.id = span.id;
81
+ result.lo = positionMap[span.lo];
82
+ result.hi = positionMap[span.hi];
83
+ return result;
84
+ });
85
+ return breakpoint_spans;
86
+ }
87
+ async captureQuantumState() {
88
+ const state = this.debugService.capture_quantum_state();
89
+ const entries = state.entries.map((entry) => {
90
+ const result = {};
91
+ result.name = entry.name;
92
+ result.value = entry.value;
93
+ return result;
94
+ });
95
+ return entries;
96
+ }
97
+ async getLocalVariables() {
98
+ const variable_list = this.debugService.get_locals();
99
+ const variables = variable_list.variables.map((variable) => {
100
+ const result = {};
101
+ result.name = variable.name;
102
+ result.value = variable.value;
103
+ result.var_type = variable.var_type;
104
+ return result;
105
+ });
106
+ return variables;
107
+ }
108
+ async dispose() {
109
+ this.debugService.free();
110
+ }
111
+ }
112
+ export function onCompilerEvent(msg, eventTarget) {
113
+ const qscMsg = eventStringToMsg(msg);
114
+ if (!qscMsg) {
115
+ log.error("Unknown event message: %s", msg);
116
+ return;
117
+ }
118
+ let qscEvent;
119
+ const msgType = qscMsg.type;
120
+ switch (msgType) {
121
+ case "Message":
122
+ qscEvent = makeEvent("Message", qscMsg.message);
123
+ break;
124
+ case "DumpMachine":
125
+ qscEvent = makeEvent("DumpMachine", qscMsg.state);
126
+ break;
127
+ case "Result":
128
+ qscEvent = makeEvent("Result", qscMsg.result);
129
+ break;
130
+ default:
131
+ log.never(msgType);
132
+ throw "Unexpected message type";
133
+ }
134
+ log.debug("worker dispatching event " + JSON.stringify(qscEvent));
135
+ eventTarget.dispatchEvent(qscEvent);
136
+ }
@@ -0,0 +1 @@
1
+ export declare function messageHandler(e: MessageEvent): void;
@@ -0,0 +1,32 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import * as wasm from "../../lib/web/qsc_wasm.js";
4
+ import { log } from "../log.js";
5
+ import { QSharpDebugService } from "./debug-service.js";
6
+ import { createDebugServiceDispatcher } from "./worker-proxy.js";
7
+ let invokeDebugger = null;
8
+ // This export should be assigned to 'self.onmessage' in a WebWorker
9
+ export function messageHandler(e) {
10
+ const data = e.data;
11
+ if (!data.type || typeof data.type !== "string") {
12
+ log.error(`Unrecognized msg: ${data}`);
13
+ return;
14
+ }
15
+ switch (data.type) {
16
+ case "init":
17
+ {
18
+ log.setLogLevel(data.qscLogLevel);
19
+ wasm.initSync(data.wasmModule);
20
+ const debugService = new QSharpDebugService(wasm);
21
+ invokeDebugger = createDebugServiceDispatcher(self.postMessage.bind(self), debugService);
22
+ }
23
+ break;
24
+ default:
25
+ if (!invokeDebugger) {
26
+ log.error(`Received message before the debugger was initialized: %o`, data);
27
+ }
28
+ else {
29
+ invokeDebugger(data);
30
+ }
31
+ }
32
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ // This module supports running the qsharp debugger in a Node.js worker thread. It should be
4
+ // used in a Node.js module in a manner similar to the below to create it with the right log level:
5
+ //
6
+ // const worker = new Worker(join(thisDir,"worker-node.js"), {
7
+ // workerData: {qscLogLevel: log.getLogLevel() }
8
+ // });
9
+ import { isMainThread, parentPort, workerData } from "node:worker_threads";
10
+ import * as wasm from "../../lib/node/qsc_wasm.cjs";
11
+ import { log } from "../log.js";
12
+ import { QSharpDebugService } from "./debug-service.js";
13
+ import { createDebugServiceDispatcher } from "./worker-proxy.js";
14
+ if (isMainThread)
15
+ throw "Worker script should be loaded in a Worker thread only";
16
+ if (workerData && typeof workerData.qscLogLevel === "number") {
17
+ log.setLogLevel(workerData.qscLogLevel);
18
+ }
19
+ const port = parentPort; // eslint-disable-line @typescript-eslint/no-non-null-assertion
20
+ const postMessage = port.postMessage.bind(port);
21
+ const debuggerd = new QSharpDebugService(wasm);
22
+ const invokeDebugger = createDebugServiceDispatcher(postMessage, debuggerd);
23
+ function messageHandler(data) {
24
+ if (!data.type || typeof data.type !== "string") {
25
+ log.error(`Unrecognized msg: %O"`, data);
26
+ return;
27
+ }
28
+ invokeDebugger(data);
29
+ }
30
+ port.addListener("message", messageHandler);
@@ -0,0 +1,7 @@
1
+ import { QscEventData } from "../compiler/events.js";
2
+ import { EventMessage, RequestMessage, ResponseMessage } from "../worker-proxy.js";
3
+ import { IDebugService } from "./debug-service.js";
4
+ export declare function createDebugServiceDispatcher(postMessage: (msg: ResponseMessage<IDebugService> | EventMessage<QscEventData>) => void, service: IDebugService): (req: RequestMessage<IDebugService>) => any;
5
+ export declare function createDebugServiceProxy(postMessage: (msg: RequestMessage<IDebugService>) => void, terminator: () => void): IDebugService & import("../worker-proxy.js").IServiceProxy & {
6
+ onMsgFromWorker: (msg: EventMessage<QscEventData> | ResponseMessage<IDebugService>) => void;
7
+ };
@@ -0,0 +1,22 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import { createDispatcher, createProxy, } from "../worker-proxy.js";
4
+ const requests = {
5
+ loadSource: "request",
6
+ getBreakpoints: "request",
7
+ getLocalVariables: "request",
8
+ captureQuantumState: "request",
9
+ getStackFrames: "request",
10
+ evalContinue: "requestWithProgress",
11
+ evalNext: "requestWithProgress",
12
+ evalStepIn: "requestWithProgress",
13
+ evalStepOut: "requestWithProgress",
14
+ dispose: "request",
15
+ };
16
+ const events = ["DumpMachine", "Message", "Result"];
17
+ export function createDebugServiceDispatcher(postMessage, service) {
18
+ return createDispatcher(postMessage, service, requests, events);
19
+ }
20
+ export function createDebugServiceProxy(postMessage, terminator) {
21
+ return createProxy(postMessage, terminator, requests);
22
+ }
@@ -0,0 +1,61 @@
1
+ declare const _default: {
2
+ katas: {
3
+ id: string;
4
+ title: string;
5
+ sections: ({
6
+ type: string;
7
+ id: string;
8
+ title: string;
9
+ items: ({
10
+ type: string;
11
+ asHtml: string;
12
+ asMarkdown: string;
13
+ id?: undefined;
14
+ code?: undefined;
15
+ } | {
16
+ type: string;
17
+ id: string;
18
+ code: string;
19
+ asHtml?: undefined;
20
+ asMarkdown?: undefined;
21
+ })[];
22
+ description?: undefined;
23
+ sourceIds?: undefined;
24
+ placeholderCode?: undefined;
25
+ explainedSolution?: undefined;
26
+ } | {
27
+ type: string;
28
+ id: string;
29
+ title: string;
30
+ description: {
31
+ type: string;
32
+ asHtml: string;
33
+ asMarkdown: string;
34
+ };
35
+ sourceIds: string[];
36
+ placeholderCode: string;
37
+ explainedSolution: {
38
+ type: string;
39
+ items: ({
40
+ type: string;
41
+ asHtml: string;
42
+ asMarkdown: string;
43
+ id?: undefined;
44
+ code?: undefined;
45
+ } | {
46
+ type: string;
47
+ id: string;
48
+ code: string;
49
+ asHtml?: undefined;
50
+ asMarkdown?: undefined;
51
+ })[];
52
+ };
53
+ items?: undefined;
54
+ })[];
55
+ }[];
56
+ globalCodeSources: {
57
+ id: string;
58
+ code: string;
59
+ }[];
60
+ };
61
+ export default _default;