Skip to content

Commit 9039300

Browse files
mattmassonMatt Masson
andauthored
Fix onModuleLibraryUpdated call (#312)
Co-authored-by: Matt Masson <mmasson@microsoft.com>
1 parent e9ac2ff commit 9039300

File tree

4 files changed

+101
-40
lines changed

4 files changed

+101
-40
lines changed

src/common/PQTestService.ts

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* LICENSE file in the root of this projects source tree.
66
*/
77

8+
import * as PQLSExt from "./vscode-powerquery.api.d";
9+
810
import { PQTestTask } from "./PowerQueryTask";
911
import type { ValueEventEmitter } from "./ValueEventEmitter";
1012

@@ -134,43 +136,33 @@ export interface IPQTestService {
134136

135137
const CommonArgs: string[] = ["--prettyPrint"];
136138

137-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
138-
export function convertExtensionInfoToLibraryJson(extensionInfos: ExtensionInfo[]): any[] {
139-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
140-
const result: any[] = [];
139+
export function convertExtensionInfoToLibraryJson(extensionInfos: ExtensionInfo[]): PQLSExt.LibraryJson {
140+
const libraryExports: PQLSExt.LibraryExportJson[] = [];
141141

142142
for (const oneInfo of extensionInfos) {
143143
if (oneInfo.Members && Array.isArray(oneInfo.Members)) {
144-
for (const oneInfoMemeber of oneInfo.Members) {
145-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
146-
const one: any = {};
147-
148-
one.name = oneInfoMemeber.Name;
149-
one.completionItemType = oneInfoMemeber.CompletionItemType;
150-
one.isDataSource = oneInfoMemeber.IsDataSource;
151-
one.dataType = oneInfoMemeber.DataTypeOrReturnType;
152-
153-
if (oneInfoMemeber.Documentation && Array.isArray(oneInfoMemeber.Documentation)) {
154-
one.documentation = [];
155-
156-
for (const oneInfoMemberDoc of oneInfoMemeber.Documentation) {
157-
one.documentation.push({
158-
description: oneInfoMemberDoc.Description ?? null,
159-
longDescription: oneInfoMemberDoc.LongDescription ?? null,
160-
category: oneInfoMemberDoc.Category ?? null,
161-
});
162-
}
163-
} else {
164-
one.documentation = null;
165-
}
166-
167-
if (oneInfoMemeber.FunctionParameters && Array.isArray(oneInfoMemeber.FunctionParameters)) {
168-
one.functionParameters = [];
169-
170-
for (const oneInfoMemberPara of oneInfoMemeber.FunctionParameters) {
171-
one.functionParameters.push({
144+
for (const oneInfoMember of oneInfo.Members) {
145+
// TODO: language extension expects a single member rather than an array.
146+
// if (oneInfoMember.Documentation && Array.isArray(oneInfoMember.Documentation)) {
147+
// one.documentation = [];
148+
149+
// for (const oneInfoMemberDoc of oneInfoMember.Documentation) {
150+
// one.documentation.push({
151+
// description: oneInfoMemberDoc.Description ?? null,
152+
// longDescription: oneInfoMemberDoc.LongDescription ?? null,
153+
// });
154+
// }
155+
// } else {
156+
// one.documentation = null;
157+
// }
158+
159+
const functionParameters: PQLSExt.LibraryFunctionParameterJson[] = [];
160+
161+
if (oneInfoMember.FunctionParameters && Array.isArray(oneInfoMember.FunctionParameters)) {
162+
for (const oneInfoMemberPara of oneInfoMember.FunctionParameters) {
163+
functionParameters.push({
172164
name: oneInfoMemberPara.Name,
173-
parameterType: oneInfoMemberPara.ParameterType,
165+
type: oneInfoMemberPara.ParameterType,
174166
isRequired: oneInfoMemberPara.IsRequired,
175167
isNullable: oneInfoMemberPara.IsNullable,
176168
caption: oneInfoMemberPara.Caption ?? null,
@@ -194,16 +186,23 @@ export function convertExtensionInfoToLibraryJson(extensionInfos: ExtensionInfo[
194186
enumCaptions: oneInfoMemberPara.EnumCaptions ?? null,
195187
});
196188
}
197-
} else {
198-
one.functionParameters = null;
199189
}
200190

201-
result.push(one);
191+
const one: PQLSExt.LibraryExportJson = {
192+
name: oneInfoMember.Name,
193+
documentation: null,
194+
completionItemKind: oneInfoMember.CompletionItemType,
195+
functionParameters: functionParameters.length > 0 ? functionParameters : null,
196+
isDataSource: oneInfoMember.IsDataSource,
197+
type: oneInfoMember.DataTypeOrReturnType,
198+
};
199+
200+
libraryExports.push(one);
202201
}
203202
}
204203
}
205204

206-
return result;
205+
return libraryExports;
207206
}
208207

209208
export function buildPqTestArgs(pqTestTask: PQTestTask): string[] {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright (c) Microsoft Corporation.
3+
*
4+
* Licensed under the MIT license found in the
5+
* LICENSE file in the root of this projects source tree.
6+
*/
7+
8+
// Must be kept in sync with vscode-powerquery extension API.
9+
// https://github.com/microsoft/vscode-powerquery/blob/master/client/src/vscode-powerquery.api.d.ts
10+
// TODO: Add a way to import API as npm module or sync from original code base.
11+
12+
// The JSON output of a localized standard library.
13+
export type LibraryJson = ReadonlyArray<LibraryExportJson>;
14+
15+
export interface LibraryExportJson {
16+
readonly name: string;
17+
readonly documentation: LibraryDocumentationJson | null;
18+
readonly functionParameters: ReadonlyArray<LibraryFunctionParameterJson> | null;
19+
readonly completionItemKind: number;
20+
readonly isDataSource: boolean;
21+
readonly type: string;
22+
}
23+
24+
export interface LibraryDocumentationJson {
25+
readonly description: string | null;
26+
readonly longDescription: string | null;
27+
}
28+
29+
export interface LibraryFunctionParameterJson {
30+
readonly name: string;
31+
readonly type: string;
32+
readonly isRequired: boolean;
33+
readonly isNullable: boolean;
34+
readonly caption: string | null;
35+
readonly description: string | null;
36+
readonly sampleValues: ReadonlyArray<string | number> | null;
37+
readonly allowedValues: ReadonlyArray<string | number> | null;
38+
readonly defaultValue: string | number | null;
39+
readonly fields: ReadonlyArray<LibraryFieldJson> | null;
40+
readonly enumNames: ReadonlyArray<string> | null;
41+
readonly enumCaptions: ReadonlyArray<string> | ReadonlyArray<null> | null;
42+
}
43+
44+
export interface LibraryFieldJson {
45+
readonly name: string;
46+
readonly type: string;
47+
readonly isRequired: boolean;
48+
readonly caption: string | null;
49+
readonly description: string | null;
50+
}
51+
52+
export interface PowerQueryApi {
53+
readonly onModuleLibraryUpdated: (workspaceUriPath: string, library: LibraryJson) => void;
54+
}

src/extension.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
import * as vscode from "vscode";
99

10+
import * as PQLSExt from "./common/vscode-powerquery.api.d";
11+
1012
import { convertExtensionInfoToLibraryJson, ExtensionInfo, IPQTestService } from "./common/PQTestService";
1113
import { getFirstWorkspaceFolder, maybeHandleNewWorkspaceCreated } from "./utils/vscodes";
1214
import { activateMQueryDebug } from "./debugAdaptor/activateMQueryDebug";
@@ -22,10 +24,12 @@ import { PqSdkOutputChannel } from "./features/PqSdkOutputChannel";
2224
import { PqServiceHostClient } from "./pqTestConnector/PqServiceHostClient";
2325
import { PqTestExecutableTaskQueue } from "./pqTestConnector/PqTestExecutableTaskQueue";
2426
import { PqTestResultViewPanel } from "./panels/PqTestResultViewPanel";
27+
import { stringifyJson } from "./utils/strings";
2528

2629
export function activate(vscExtCtx: vscode.ExtensionContext): void {
27-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
28-
const vscPowerQuery: any = vscode.extensions.getExtension(ExtensionConstants.PQLanguageServiceExtensionId)?.exports;
30+
const vscPowerQuery: PQLSExt.PowerQueryApi = vscode.extensions.getExtension(
31+
ExtensionConstants.PQLanguageServiceExtensionId,
32+
)?.exports;
2933

3034
const useServiceHost: boolean = ExtensionConfigurations.featureUseServiceHost;
3135

@@ -51,7 +55,9 @@ export function activate(vscExtCtx: vscode.ExtensionContext): void {
5155
const theUri: vscode.Uri | undefined = getFirstWorkspaceFolder()?.uri;
5256

5357
if (theUri) {
54-
vscPowerQuery.onModuleLibraryUpdated(theUri.toString(), convertExtensionInfoToLibraryJson(infos));
58+
const libraryExports: PQLSExt.LibraryJson = convertExtensionInfoToLibraryJson(infos);
59+
pqSdkOutputChannel?.appendDebugLine(`onModuleLibraryUpdated: ${stringifyJson(libraryExports)}`);
60+
vscPowerQuery.onModuleLibraryUpdated(theUri.toString(), libraryExports);
5561
}
5662
});
5763

src/test/suite/extension.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ suite("Extension Test Suite", () => {
3030
assert.equal(languageServiceExtension.isActive, true, "Language service extension failed to activate");
3131
});
3232
});
33+
34+
// TODO: Add onModuleLibraryUpdated test when language service extension returns a result that can be validated.
3335
});

0 commit comments

Comments
 (0)