qsharp-lang 1.0.28-dev → 1.0.30-dev
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.
- package/dist/browser.d.ts +7 -1
- package/dist/browser.js +6 -2
- package/dist/compiler/compiler.d.ts +6 -6
- package/dist/compiler/compiler.js +16 -8
- package/dist/debug-service/debug-service.d.ts +2 -2
- package/dist/debug-service/debug-service.js +5 -3
- package/dist/language-service/language-service.d.ts +9 -4
- package/dist/language-service/language-service.js +50 -33
- package/dist/main.d.ts +7 -1
- package/dist/main.js +11 -2
- package/lib/node/qsc_wasm.cjs +250 -101
- package/lib/node/qsc_wasm.d.cts +40 -14
- package/lib/node/qsc_wasm_bg.wasm +0 -0
- package/lib/web/qsc_wasm.d.ts +53 -19
- package/lib/web/qsc_wasm.js +237 -98
- package/lib/web/qsc_wasm_bg.wasm +0 -0
- package/package.json +1 -1
- package/ux/index.ts +1 -1
- package/ux/reTable.tsx +1 -0
- package/ux/resultsTable.tsx +40 -5
package/dist/browser.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as wasm from "../lib/web/qsc_wasm.js";
|
|
1
2
|
import { TargetProfile } from "../lib/web/qsc_wasm.js";
|
|
2
3
|
import { ICompiler, ICompilerWorker } from "./compiler/compiler.js";
|
|
3
4
|
import { IDebugService, IDebugServiceWorker } from "./debug-service/debug-service.js";
|
|
@@ -7,10 +8,15 @@ export { qsharpLibraryUriScheme };
|
|
|
7
8
|
export declare function loadWasmModule(uriOrBuffer: string | ArrayBuffer): Promise<void>;
|
|
8
9
|
export declare function getLibrarySourceContent(path: string): Promise<string | undefined>;
|
|
9
10
|
export declare function getDebugService(): Promise<IDebugService>;
|
|
11
|
+
export declare function getProjectLoader(readFile: (path: string) => Promise<string | null>, loadDirectory: (path: string) => Promise<[string, number][]>, getManifest: (path: string) => Promise<{
|
|
12
|
+
manifestDirectory: string;
|
|
13
|
+
} | null>): Promise<wasm.ProjectLoader>;
|
|
10
14
|
export declare function getDebugServiceWorker(workerArg: string | Worker): IDebugServiceWorker;
|
|
11
15
|
export declare function getCompiler(): Promise<ICompiler>;
|
|
12
16
|
export declare function getCompilerWorker(workerArg: string | Worker): ICompilerWorker;
|
|
13
|
-
export declare function getLanguageService(): Promise<
|
|
17
|
+
export declare function getLanguageService(readFile?: (uri: string) => Promise<string | null>, listDir?: (uri: string) => Promise<[string, number][]>, getManifest?: (uri: string) => Promise<{
|
|
18
|
+
manifestDirectory: string;
|
|
19
|
+
} | null>): Promise<ILanguageService>;
|
|
14
20
|
export declare function getLanguageServiceWorker(workerArg: string | Worker): ILanguageServiceWorker;
|
|
15
21
|
export { type Dump, type ShotResult } from "./compiler/common.js";
|
|
16
22
|
export { type CompilerState } from "./compiler/compiler.js";
|
package/dist/browser.js
CHANGED
|
@@ -72,6 +72,10 @@ export async function getDebugService() {
|
|
|
72
72
|
await instantiateWasm();
|
|
73
73
|
return new QSharpDebugService(wasm);
|
|
74
74
|
}
|
|
75
|
+
export async function getProjectLoader(readFile, loadDirectory, getManifest) {
|
|
76
|
+
await instantiateWasm();
|
|
77
|
+
return new wasm.ProjectLoader(readFile, loadDirectory, getManifest);
|
|
78
|
+
}
|
|
75
79
|
// Create the debugger inside a WebWorker and proxy requests.
|
|
76
80
|
// If the Worker was already created via other means and is ready to receive
|
|
77
81
|
// messages, then the worker may be passed in and it will be initialized.
|
|
@@ -122,9 +126,9 @@ export function getCompilerWorker(workerArg) {
|
|
|
122
126
|
worker.onmessage = (ev) => proxy.onMsgFromWorker(ev.data);
|
|
123
127
|
return proxy;
|
|
124
128
|
}
|
|
125
|
-
export async function getLanguageService() {
|
|
129
|
+
export async function getLanguageService(readFile, listDir, getManifest) {
|
|
126
130
|
await instantiateWasm();
|
|
127
|
-
return new QSharpLanguageService(wasm);
|
|
131
|
+
return new QSharpLanguageService(wasm, readFile, listDir, getManifest);
|
|
128
132
|
}
|
|
129
133
|
// Create the compiler inside a WebWorker and proxy requests.
|
|
130
134
|
// If the Worker was already created via other means and is ready to receive
|
|
@@ -5,9 +5,9 @@ type Wasm = typeof import("../../lib/node/qsc_wasm.cjs");
|
|
|
5
5
|
export interface ICompiler {
|
|
6
6
|
checkCode(code: string): Promise<VSDiagnostic[]>;
|
|
7
7
|
getHir(code: string): Promise<string>;
|
|
8
|
-
run(
|
|
9
|
-
getQir(
|
|
10
|
-
getEstimates(
|
|
8
|
+
run(sources: [string, string][], expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
|
|
9
|
+
getQir(sources: [string, string][]): Promise<string>;
|
|
10
|
+
getEstimates(sources: [string, string][], params: string): Promise<string>;
|
|
11
11
|
checkExerciseSolution(user_code: string, exercise_sources: string[], eventHandler: IQscEventTarget): Promise<boolean>;
|
|
12
12
|
}
|
|
13
13
|
export type ICompilerWorker = ICompiler & IServiceProxy;
|
|
@@ -16,10 +16,10 @@ export declare class Compiler implements ICompiler {
|
|
|
16
16
|
private wasm;
|
|
17
17
|
constructor(wasm: Wasm);
|
|
18
18
|
checkCode(code: string): Promise<VSDiagnostic[]>;
|
|
19
|
-
getQir(
|
|
20
|
-
getEstimates(
|
|
19
|
+
getQir(sources: [string, string][]): Promise<string>;
|
|
20
|
+
getEstimates(sources: [string, string][], params: string): Promise<string>;
|
|
21
21
|
getHir(code: string): Promise<string>;
|
|
22
|
-
run(
|
|
22
|
+
run(sources: [string, string][], expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
|
|
23
23
|
checkExerciseSolution(user_code: string, exercise_sources: string[], eventHandler: IQscEventTarget): Promise<boolean>;
|
|
24
24
|
}
|
|
25
25
|
export declare function onCompilerEvent(msg: string, eventTarget: IQscEventTarget): void;
|
|
@@ -10,28 +10,36 @@ export class Compiler {
|
|
|
10
10
|
this.wasm = wasm;
|
|
11
11
|
globalThis.qscGitHash = this.wasm.git_hash();
|
|
12
12
|
}
|
|
13
|
+
// Note: This function does not support project mode.
|
|
14
|
+
// see https://github.com/microsoft/qsharp/pull/849#discussion_r1409821143
|
|
13
15
|
async checkCode(code) {
|
|
14
16
|
let diags = [];
|
|
15
|
-
const languageService = new this.wasm.LanguageService(
|
|
17
|
+
const languageService = new this.wasm.LanguageService();
|
|
18
|
+
const work = languageService.start_background_work((uri, version, errors) => {
|
|
16
19
|
diags = errors;
|
|
17
|
-
});
|
|
20
|
+
}, () => Promise.resolve(null), () => Promise.resolve([]), () => Promise.resolve(null));
|
|
18
21
|
languageService.update_document("code", 1, code);
|
|
22
|
+
// Yield to let the language service background worker handle the update
|
|
23
|
+
await Promise.resolve();
|
|
24
|
+
languageService.stop_background_work();
|
|
25
|
+
await work;
|
|
26
|
+
languageService.free();
|
|
19
27
|
return mapDiagnostics(diags, code);
|
|
20
28
|
}
|
|
21
|
-
async getQir(
|
|
22
|
-
return this.wasm.get_qir(
|
|
29
|
+
async getQir(sources) {
|
|
30
|
+
return this.wasm.get_qir(sources);
|
|
23
31
|
}
|
|
24
|
-
async getEstimates(
|
|
25
|
-
return this.wasm.get_estimates(
|
|
32
|
+
async getEstimates(sources, params) {
|
|
33
|
+
return this.wasm.get_estimates(sources, params);
|
|
26
34
|
}
|
|
27
35
|
async getHir(code) {
|
|
28
36
|
return this.wasm.get_hir(code);
|
|
29
37
|
}
|
|
30
|
-
async run(
|
|
38
|
+
async run(sources, expr, shots, eventHandler) {
|
|
31
39
|
// All results are communicated as events, but if there is a compiler error (e.g. an invalid
|
|
32
40
|
// entry expression or similar), it may throw on run. The caller should expect this promise
|
|
33
41
|
// may reject without all shots running or events firing.
|
|
34
|
-
this.wasm.run(
|
|
42
|
+
this.wasm.run(sources, expr, (msg) => onCompilerEvent(msg, eventHandler), shots);
|
|
35
43
|
}
|
|
36
44
|
async checkExerciseSolution(user_code, exercise_sources, eventHandler) {
|
|
37
45
|
const success = this.wasm.check_exercise_solution(user_code, exercise_sources, (msg) => onCompilerEvent(msg, eventHandler));
|
|
@@ -4,7 +4,7 @@ import { IQscEventTarget } from "../compiler/events.js";
|
|
|
4
4
|
import { IServiceProxy } from "../worker-proxy.js";
|
|
5
5
|
type QscWasm = typeof import("../../lib/node/qsc_wasm.cjs");
|
|
6
6
|
export interface IDebugService {
|
|
7
|
-
loadSource(
|
|
7
|
+
loadSource(sources: [string, string][], target: TargetProfile, entry: string | undefined): Promise<string>;
|
|
8
8
|
getBreakpoints(path: string): Promise<IBreakpointSpan[]>;
|
|
9
9
|
getLocalVariables(): Promise<Array<IVariable>>;
|
|
10
10
|
captureQuantumState(): Promise<Array<IQuantumState>>;
|
|
@@ -21,7 +21,7 @@ export declare class QSharpDebugService implements IDebugService {
|
|
|
21
21
|
private debugService;
|
|
22
22
|
private code;
|
|
23
23
|
constructor(wasm: QscWasm);
|
|
24
|
-
loadSource(
|
|
24
|
+
loadSource(sources: [string, string][], target: TargetProfile, entry: string | undefined): Promise<string>;
|
|
25
25
|
getStackFrames(): Promise<IStackFrame[]>;
|
|
26
26
|
evalNext(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
|
|
27
27
|
evalStepIn(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
|
|
@@ -12,9 +12,11 @@ export class QSharpDebugService {
|
|
|
12
12
|
this.wasm = wasm;
|
|
13
13
|
this.debugService = new wasm.DebugService();
|
|
14
14
|
}
|
|
15
|
-
async loadSource(
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
async loadSource(sources, target, entry) {
|
|
16
|
+
for (const [path, source] of sources) {
|
|
17
|
+
this.code[path] = source;
|
|
18
|
+
}
|
|
19
|
+
return this.debugService.load_source(sources, target, entry);
|
|
18
20
|
}
|
|
19
21
|
async getStackFrames() {
|
|
20
22
|
const stack_frame_list = this.debugService.get_stack_frames();
|
|
@@ -19,7 +19,7 @@ export interface ILanguageService {
|
|
|
19
19
|
code: string;
|
|
20
20
|
}[]): Promise<void>;
|
|
21
21
|
closeDocument(uri: string): Promise<void>;
|
|
22
|
-
closeNotebookDocument(notebookUri: string
|
|
22
|
+
closeNotebookDocument(notebookUri: string): Promise<void>;
|
|
23
23
|
getCompletions(documentUri: string, offset: number): Promise<ICompletionList>;
|
|
24
24
|
getHover(documentUri: string, offset: number): Promise<IHover | undefined>;
|
|
25
25
|
getDefinition(documentUri: string, offset: number): Promise<ILocation | undefined>;
|
|
@@ -41,7 +41,12 @@ export declare class QSharpLanguageService implements ILanguageService {
|
|
|
41
41
|
private languageService;
|
|
42
42
|
private eventHandler;
|
|
43
43
|
private code;
|
|
44
|
-
|
|
44
|
+
private readFile;
|
|
45
|
+
private backgroundWork;
|
|
46
|
+
constructor(wasm: QscWasm, readFile?: (uri: string) => Promise<string | null>, listDir?: (uri: string) => Promise<[string, number][]>, getManifest?: (uri: string) => Promise<{
|
|
47
|
+
manifestDirectory: string;
|
|
48
|
+
} | null>);
|
|
49
|
+
loadFile(uri: string): Promise<string | null>;
|
|
45
50
|
updateConfiguration(config: IWorkspaceConfiguration): Promise<void>;
|
|
46
51
|
updateDocument(documentUri: string, version: number, code: string): Promise<void>;
|
|
47
52
|
updateNotebookDocument(notebookUri: string, version: number, metadata: INotebookMetadata, cells: {
|
|
@@ -50,7 +55,7 @@ export declare class QSharpLanguageService implements ILanguageService {
|
|
|
50
55
|
code: string;
|
|
51
56
|
}[]): Promise<void>;
|
|
52
57
|
closeDocument(documentUri: string): Promise<void>;
|
|
53
|
-
closeNotebookDocument(documentUri: string
|
|
58
|
+
closeNotebookDocument(documentUri: string): Promise<void>;
|
|
54
59
|
getCompletions(documentUri: string, offset: number): Promise<ICompletionList>;
|
|
55
60
|
getHover(documentUri: string, offset: number): Promise<IHover | undefined>;
|
|
56
61
|
getDefinition(documentUri: string, offset: number): Promise<ILocation | undefined>;
|
|
@@ -65,6 +70,6 @@ export declare class QSharpLanguageService implements ILanguageService {
|
|
|
65
70
|
removeEventListener<T extends LanguageServiceEvent["type"]>(type: T, listener: (event: Extract<LanguageServiceEvent, {
|
|
66
71
|
type: T;
|
|
67
72
|
}>) => void): void;
|
|
68
|
-
onDiagnostics(uri: string, version: number | undefined, diagnostics: VSDiagnostic[]): void
|
|
73
|
+
onDiagnostics(uri: string, version: number | undefined, diagnostics: VSDiagnostic[]): Promise<void>;
|
|
69
74
|
}
|
|
70
75
|
export {};
|
|
@@ -5,12 +5,25 @@ import { log } from "../log.js";
|
|
|
5
5
|
import { mapDiagnostics, mapUtf16UnitsToUtf8Units, mapUtf8UnitsToUtf16Units, } from "../vsdiagnostic.js";
|
|
6
6
|
export const qsharpLibraryUriScheme = "qsharp-library-source";
|
|
7
7
|
export class QSharpLanguageService {
|
|
8
|
-
constructor(wasm) {
|
|
8
|
+
constructor(wasm, readFile = () => Promise.resolve(null), listDir = () => Promise.resolve([]), getManifest = () => Promise.resolve(null)) {
|
|
9
9
|
this.eventHandler = new EventTarget();
|
|
10
10
|
// We need to keep a copy of the code for mapping diagnostics to utf16 offsets
|
|
11
11
|
this.code = {};
|
|
12
12
|
log.info("Constructing a QSharpLanguageService instance");
|
|
13
|
-
this.languageService = new wasm.LanguageService(
|
|
13
|
+
this.languageService = new wasm.LanguageService();
|
|
14
|
+
this.backgroundWork = this.languageService.start_background_work(this.onDiagnostics.bind(this), readFile, listDir, getManifest);
|
|
15
|
+
this.readFile = readFile;
|
|
16
|
+
}
|
|
17
|
+
async loadFile(uri) {
|
|
18
|
+
const result = this.code[uri];
|
|
19
|
+
if (result === undefined || result === null) {
|
|
20
|
+
return await this.readFile(uri);
|
|
21
|
+
}
|
|
22
|
+
if (result === null || result === undefined) {
|
|
23
|
+
log.error("File", uri, "wasn't in document map when we expected it to be");
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
14
27
|
}
|
|
15
28
|
async updateConfiguration(config) {
|
|
16
29
|
this.languageService.update_configuration(config);
|
|
@@ -32,13 +45,12 @@ export class QSharpLanguageService {
|
|
|
32
45
|
delete this.code[documentUri];
|
|
33
46
|
this.languageService.close_document(documentUri);
|
|
34
47
|
}
|
|
35
|
-
async closeNotebookDocument(documentUri
|
|
36
|
-
|
|
37
|
-
this.languageService.close_notebook_document(documentUri, cellUris);
|
|
48
|
+
async closeNotebookDocument(documentUri) {
|
|
49
|
+
this.languageService.close_notebook_document(documentUri);
|
|
38
50
|
}
|
|
39
51
|
async getCompletions(documentUri, offset) {
|
|
40
|
-
const code = this.
|
|
41
|
-
if (code ===
|
|
52
|
+
const code = await this.loadFile(documentUri);
|
|
53
|
+
if (code === null) {
|
|
42
54
|
log.error(`getCompletions: expected ${documentUri} to be in the document map`);
|
|
43
55
|
return { items: [] };
|
|
44
56
|
}
|
|
@@ -50,8 +62,8 @@ export class QSharpLanguageService {
|
|
|
50
62
|
return result;
|
|
51
63
|
}
|
|
52
64
|
async getHover(documentUri, offset) {
|
|
53
|
-
const code = this.
|
|
54
|
-
if (code ===
|
|
65
|
+
const code = await this.loadFile(documentUri);
|
|
66
|
+
if (code === null) {
|
|
55
67
|
log.error(`getHover: expected ${documentUri} to be in the document map`);
|
|
56
68
|
return undefined;
|
|
57
69
|
}
|
|
@@ -63,22 +75,22 @@ export class QSharpLanguageService {
|
|
|
63
75
|
return result;
|
|
64
76
|
}
|
|
65
77
|
async getDefinition(documentUri, offset) {
|
|
66
|
-
const sourceCode = this.
|
|
67
|
-
if (sourceCode === undefined) {
|
|
78
|
+
const sourceCode = await this.loadFile(documentUri);
|
|
79
|
+
if (sourceCode === undefined || sourceCode === null) {
|
|
68
80
|
log.error(`getDefinition: expected ${documentUri} to be in the document map`);
|
|
69
81
|
return undefined;
|
|
70
82
|
}
|
|
71
83
|
const convertedOffset = mapUtf16UnitsToUtf8Units([offset], sourceCode)[offset];
|
|
72
84
|
const result = this.languageService.get_definition(documentUri, convertedOffset);
|
|
73
85
|
if (result) {
|
|
74
|
-
let targetCode = this.
|
|
75
|
-
if (targetCode ===
|
|
86
|
+
let targetCode = (await this.loadFile(result.source)) || null;
|
|
87
|
+
if (targetCode === null) {
|
|
76
88
|
// Inspect the URL protocol (equivalent to the URI scheme + ":").
|
|
77
89
|
// If the scheme is our library scheme, we need to call the wasm to
|
|
78
90
|
// provide the library file's contents to do the utf8->utf16 mapping.
|
|
79
91
|
const url = new URL(result.source);
|
|
80
92
|
if (url.protocol === qsharpLibraryUriScheme + ":") {
|
|
81
|
-
targetCode = wasm.get_library_source_content(url.pathname);
|
|
93
|
+
targetCode = wasm.get_library_source_content(url.pathname) || null;
|
|
82
94
|
if (targetCode === undefined) {
|
|
83
95
|
log.error(`getDefinition: expected ${url} to be in the library`);
|
|
84
96
|
return undefined;
|
|
@@ -96,8 +108,8 @@ export class QSharpLanguageService {
|
|
|
96
108
|
return result;
|
|
97
109
|
}
|
|
98
110
|
async getReferences(documentUri, offset, includeDeclaration) {
|
|
99
|
-
const sourceCode = this.
|
|
100
|
-
if (sourceCode === undefined) {
|
|
111
|
+
const sourceCode = await this.loadFile(documentUri);
|
|
112
|
+
if (sourceCode === undefined || sourceCode === null) {
|
|
101
113
|
log.error(`getReferences: expected ${documentUri} to be in the document map`);
|
|
102
114
|
return [];
|
|
103
115
|
}
|
|
@@ -106,13 +118,13 @@ export class QSharpLanguageService {
|
|
|
106
118
|
if (results && results.length > 0) {
|
|
107
119
|
const references = [];
|
|
108
120
|
for (const result of results) {
|
|
109
|
-
let resultCode = this.
|
|
121
|
+
let resultCode = await this.loadFile(result.source);
|
|
110
122
|
// Inspect the URL protocol (equivalent to the URI scheme + ":").
|
|
111
123
|
// If the scheme is our library scheme, we need to call the wasm to
|
|
112
124
|
// provide the library file's contents to do the utf8->utf16 mapping.
|
|
113
125
|
const url = new URL(result.source);
|
|
114
126
|
if (url.protocol === qsharpLibraryUriScheme + ":") {
|
|
115
|
-
resultCode = wasm.get_library_source_content(url.pathname);
|
|
127
|
+
resultCode = wasm.get_library_source_content(url.pathname) || null;
|
|
116
128
|
if (resultCode === undefined) {
|
|
117
129
|
log.error(`getReferences: expected ${url} to be in the library`);
|
|
118
130
|
}
|
|
@@ -133,8 +145,8 @@ export class QSharpLanguageService {
|
|
|
133
145
|
}
|
|
134
146
|
}
|
|
135
147
|
async getSignatureHelp(documentUri, offset) {
|
|
136
|
-
const code = this.
|
|
137
|
-
if (code ===
|
|
148
|
+
const code = await this.loadFile(documentUri);
|
|
149
|
+
if (code === null) {
|
|
138
150
|
log.error(`expected ${documentUri} to be in the document map`);
|
|
139
151
|
return undefined;
|
|
140
152
|
}
|
|
@@ -152,8 +164,8 @@ export class QSharpLanguageService {
|
|
|
152
164
|
return result;
|
|
153
165
|
}
|
|
154
166
|
async getRename(documentUri, offset, newName) {
|
|
155
|
-
const code = this.
|
|
156
|
-
if (code ===
|
|
167
|
+
const code = await this.loadFile(documentUri);
|
|
168
|
+
if (code === null) {
|
|
157
169
|
log.error(`expected ${documentUri} to be in the document map`);
|
|
158
170
|
return undefined;
|
|
159
171
|
}
|
|
@@ -161,7 +173,7 @@ export class QSharpLanguageService {
|
|
|
161
173
|
const result = this.languageService.get_rename(documentUri, convertedOffset, newName);
|
|
162
174
|
const mappedChanges = [];
|
|
163
175
|
for (const [uri, edits] of result.changes) {
|
|
164
|
-
const code = this.
|
|
176
|
+
const code = await this.loadFile(uri);
|
|
165
177
|
if (code) {
|
|
166
178
|
const mappedEdits = edits.map((edit) => {
|
|
167
179
|
updateSpanFromUtf8ToUtf16(edit.range, code);
|
|
@@ -174,8 +186,8 @@ export class QSharpLanguageService {
|
|
|
174
186
|
return result;
|
|
175
187
|
}
|
|
176
188
|
async prepareRename(documentUri, offset) {
|
|
177
|
-
const code = this.
|
|
178
|
-
if (code ===
|
|
189
|
+
const code = await this.loadFile(documentUri);
|
|
190
|
+
if (code === null) {
|
|
179
191
|
log.error(`expected ${documentUri} to be in the document map`);
|
|
180
192
|
return undefined;
|
|
181
193
|
}
|
|
@@ -187,6 +199,8 @@ export class QSharpLanguageService {
|
|
|
187
199
|
return result;
|
|
188
200
|
}
|
|
189
201
|
async dispose() {
|
|
202
|
+
this.languageService.stop_background_work();
|
|
203
|
+
await this.backgroundWork;
|
|
190
204
|
this.languageService.free();
|
|
191
205
|
}
|
|
192
206
|
addEventListener(type, listener) {
|
|
@@ -195,18 +209,21 @@ export class QSharpLanguageService {
|
|
|
195
209
|
removeEventListener(type, listener) {
|
|
196
210
|
this.eventHandler.removeEventListener(type, listener);
|
|
197
211
|
}
|
|
198
|
-
onDiagnostics(uri, version, diagnostics) {
|
|
212
|
+
async onDiagnostics(uri, version, diagnostics) {
|
|
199
213
|
try {
|
|
200
|
-
const code = this.
|
|
214
|
+
const code = await this.loadFile(uri);
|
|
201
215
|
const empty = diagnostics.length === 0;
|
|
202
|
-
if (code ===
|
|
216
|
+
if (code === null && !empty) {
|
|
203
217
|
// We need the contents of the document to convert error offsets to utf16.
|
|
204
218
|
// But the contents aren't available after a document is closed.
|
|
205
|
-
// It is possible to get
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
|
|
219
|
+
// It is possible to get diagnostics events for a document after it's been closed,
|
|
220
|
+
// since document events are handled asynchronously by the language service.
|
|
221
|
+
// We just drop those diagnostics, assuming that eventually we will receive further
|
|
222
|
+
// events that will bring the diagnostics up to date.
|
|
223
|
+
// However, if we receive an *empty* array of diagnostics for a document, we don't want
|
|
224
|
+
// to drop that update. It's necessary for the diagnostics to get cleared for a document
|
|
225
|
+
// that has been closed.
|
|
226
|
+
log.warn(`onDiagnostics: received diagnostics for ${uri} which is not in the document map`);
|
|
210
227
|
return;
|
|
211
228
|
}
|
|
212
229
|
const event = new Event("diagnostics");
|
package/dist/main.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { ICompiler, ICompilerWorker } from "./compiler/compiler.js";
|
|
2
2
|
import { ILanguageService, ILanguageServiceWorker, qsharpLibraryUriScheme } from "./language-service/language-service.js";
|
|
3
3
|
import { IDebugService, IDebugServiceWorker } from "./debug-service/debug-service.js";
|
|
4
|
+
import { ProjectLoader } from "../lib/node/qsc_wasm.cjs";
|
|
4
5
|
export { qsharpLibraryUriScheme };
|
|
5
6
|
export declare function getLibrarySourceContent(path: string): Promise<string | undefined>;
|
|
6
7
|
export declare function getCompiler(): ICompiler;
|
|
8
|
+
export declare function getProjectLoader(readFile: (path: string) => Promise<string | null>, loadDirectory: (path: string) => Promise<[string, number][]>, getManifest: (path: string) => Promise<{
|
|
9
|
+
manifestDirectory: string;
|
|
10
|
+
} | null>): ProjectLoader;
|
|
7
11
|
export declare function getCompilerWorker(): ICompilerWorker;
|
|
8
12
|
export declare function getDebugService(): IDebugService;
|
|
9
13
|
export declare function getDebugServiceWorker(): IDebugServiceWorker;
|
|
10
|
-
export declare function getLanguageService():
|
|
14
|
+
export declare function getLanguageService(readFile?: (uri: string) => Promise<string | null>, listDir?: (uri: string) => Promise<[string, number][]>, getManifest?: (uri: string) => Promise<{
|
|
15
|
+
manifestDirectory: string;
|
|
16
|
+
} | null>): ILanguageService;
|
|
11
17
|
export declare function getLanguageServiceWorker(): ILanguageServiceWorker;
|
package/dist/main.js
CHANGED
|
@@ -31,6 +31,15 @@ export function getCompiler() {
|
|
|
31
31
|
}
|
|
32
32
|
return new Compiler(wasm);
|
|
33
33
|
}
|
|
34
|
+
export function getProjectLoader(readFile, loadDirectory, getManifest) {
|
|
35
|
+
if (!wasm) {
|
|
36
|
+
wasm = require("../lib/node/qsc_wasm.cjs");
|
|
37
|
+
// Set up logging and telemetry as soon as possible after instantiating
|
|
38
|
+
wasm.initLogging(log.logWithLevel, log.getLogLevel());
|
|
39
|
+
log.onLevelChanged = (level) => wasm?.setLogLevel(level);
|
|
40
|
+
}
|
|
41
|
+
return new wasm.ProjectLoader(readFile, loadDirectory, getManifest);
|
|
42
|
+
}
|
|
34
43
|
export function getCompilerWorker() {
|
|
35
44
|
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
36
45
|
const worker = new Worker(join(thisDir, "./compiler/worker-node.js"), {
|
|
@@ -62,10 +71,10 @@ export function getDebugServiceWorker() {
|
|
|
62
71
|
worker.addListener("message", proxy.onMsgFromWorker);
|
|
63
72
|
return proxy;
|
|
64
73
|
}
|
|
65
|
-
export function getLanguageService() {
|
|
74
|
+
export function getLanguageService(readFile, listDir, getManifest) {
|
|
66
75
|
if (!wasm)
|
|
67
76
|
wasm = require("../lib/node/qsc_wasm.cjs");
|
|
68
|
-
return new QSharpLanguageService(wasm);
|
|
77
|
+
return new QSharpLanguageService(wasm, readFile, listDir, getManifest);
|
|
69
78
|
}
|
|
70
79
|
export function getLanguageServiceWorker() {
|
|
71
80
|
const thisDir = dirname(fileURLToPath(import.meta.url));
|