From 437e012174ecc478b6e2ab3a80710eaeadd70bd0 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Fri, 25 Feb 2022 20:44:48 +0100 Subject: [PATCH 1/9] Refactor webpack config to use shared config --- client/webpack.config.js | 43 ++++++++++++++++ package-lock.json | 22 +++++++++ package.json | 17 +++---- server/webpack.config.js | 45 +++++++++++++++++ shared.webpack.config.js | 55 +++++++++++++++++++++ webpack.config.js | 103 --------------------------------------- 6 files changed, 172 insertions(+), 113 deletions(-) create mode 100644 client/webpack.config.js create mode 100644 server/webpack.config.js create mode 100644 shared.webpack.config.js delete mode 100644 webpack.config.js diff --git a/client/webpack.config.js b/client/webpack.config.js new file mode 100644 index 0000000..608869b --- /dev/null +++ b/client/webpack.config.js @@ -0,0 +1,43 @@ +/* eslint-disable no-undef */ +/* eslint-disable @typescript-eslint/no-var-requires */ + +//@ts-check +/** @typedef {import('webpack').Configuration} WebpackConfig **/ + +//@ts-check +("use strict"); + +const withDefaults = require("../shared.webpack.config"); +const path = require("path"); + +/** @type WebpackConfig */ +const nodeExtensionConfig = withDefaults({ + context: path.join(__dirname), + mode: "none", + target: "node", // regular extensions run in a node context + entry: { + extension: "./src/extension.ts", + }, + output: { + filename: "[name].js", + path: path.join(__dirname, "dist"), + libraryTarget: "commonjs", + }, +}); + +/** @type WebpackConfig */ +const webExtensionConfig = withDefaults({ + context: path.join(__dirname), + mode: "none", + target: "webworker", // web extensions run in a webworker context + entry: { + extension: "./src/browser/extension.ts", + }, + output: { + filename: "[name].js", + path: path.join(__dirname, "dist", "web"), + libraryTarget: "commonjs", + }, +}); + +module.exports = [nodeExtensionConfig, webExtensionConfig]; diff --git a/package-lock.json b/package-lock.json index 77b4bcf..2a24cf1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@vscode/test-web": "^0.0.19", "assert": "^2.0.0", "eslint": "^8.8.0", + "merge-options": "^3.0.4", "mocha": "^9.2.0", "path-browserify": "^1.0.1", "process": "^0.11.10", @@ -3104,6 +3105,18 @@ "node": ">= 0.6" } }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "dev": true, + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -7362,6 +7375,15 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, + "merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "dev": true, + "requires": { + "is-plain-obj": "^2.1.0" + } + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", diff --git a/package.json b/package.json index fb9009d..7afa25e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "Formatters", "Other" ], - "browser": "./client/dist/browserClientMain", + "main": "./client/dist/extension", + "browser": "./client/dist/web/extension", "activationEvents": [ "onLanguage:galaxyworkflow" ], @@ -96,15 +97,10 @@ } }, "scripts": { - "test": "vscode-test-web --browserType=chromium --extensionDevelopmentPath=. --extensionTestsPath=dist/web/test/suite/index.js", - "pretest": "npm run compile-web", - "vscode:prepublish": "npm run package-web", - "compile-web": "webpack", - "watch-web": "webpack --watch", - "package-web": "webpack --mode production --devtool hidden-source-map", + "postinstall": "cd client && npm install && cd ../server && npm install && cd ..", "lint": "eslint ./client/src ./server/src --ext .ts,.tsx", - "run-in-browser": "npm run compile-web && vscode-test-web --browserType=chromium --extensionDevelopmentPath=. ./test-data", - "postinstall": "cd client && npm install && cd ../server && npm install && cd .." + "clean": "rimraf client/dist && rimraf server/dist", + "compile": "npm run clean && webpack --config ./client/webpack.config.js && webpack --config ./server/webpack.config.js" }, "devDependencies": { "@types/mocha": "^9.1.0", @@ -121,6 +117,7 @@ "ts-loader": "^9.2.6", "typescript": "^4.5.5", "webpack": "^5.67.0", - "webpack-cli": "^4.9.2" + "webpack-cli": "^4.9.2", + "merge-options": "^3.0.4" } } diff --git a/server/webpack.config.js b/server/webpack.config.js new file mode 100644 index 0000000..87c0385 --- /dev/null +++ b/server/webpack.config.js @@ -0,0 +1,45 @@ +/* eslint-disable no-undef */ +/* eslint-disable @typescript-eslint/no-var-requires */ + +//@ts-check +/** @typedef {import('webpack').Configuration} WebpackConfig **/ + +//@ts-check +"use strict"; + +const withDefaults = require("../shared.webpack.config"); +const path = require("path"); + +/** @type WebpackConfig */ +const nodeServerConfig = withDefaults({ + mode: "none", + context: path.join(__dirname), + target: "node", // regular extensions run in node context + entry: { + nativeServer: "./src/node/nativeServer.ts", + }, + output: { + filename: "[name].js", + path: path.join(__dirname, "dist"), + libraryTarget: "var", + library: "serverExportVar", + }, +}); + +/** @type WebpackConfig */ +const browserServerConfig = withDefaults({ + mode: "none", + context: path.join(__dirname), + target: "webworker", // web extensions run in a webworker context + entry: { + nativeServer: "./src/browser/nativeServer.ts", + }, + output: { + filename: "[name].js", + path: path.join(__dirname, "dist", "web"), + libraryTarget: "var", + library: "serverExportVar", + }, +}); + +module.exports = [nodeServerConfig, browserServerConfig]; diff --git a/shared.webpack.config.js b/shared.webpack.config.js new file mode 100644 index 0000000..8a6f0f1 --- /dev/null +++ b/shared.webpack.config.js @@ -0,0 +1,55 @@ +/* eslint-disable no-undef */ +/* eslint-disable @typescript-eslint/no-var-requires */ + +//@ts-check +"use strict"; + +//@ts-check +/** @typedef {import('webpack').Configuration} WebpackConfig **/ + +const path = require("path"); +const merge = require("merge-options"); + +module.exports = function withDefaults(/**@type WebpackConfig*/ extConfig) { + /** @type WebpackConfig */ + let defaultConfig = { + mode: "none", // this leaves the source code as close as possible to the original (when packaging we set this to 'production') + target: "node", // extensions run in node context + node: { + __dirname: false, // leave the __dirname-behaviour intact + }, + resolve: { + mainFields: ["module", "main"], + extensions: [".ts", ".js"], // support ts-files and js-files + }, + module: { + rules: [ + { + test: /\.ts$/, + exclude: /node_modules/, + use: [ + { + loader: "ts-loader", + options: { + compilerOptions: { + sourceMap: true, + }, + }, + }, + ], + }, + ], + }, + externals: { + vscode: "commonjs vscode", + }, + output: { + filename: "[name].js", + path: path.join(extConfig.context, "dist"), + libraryTarget: "commonjs", + }, + devtool: "source-map", + }; + + return merge(defaultConfig, extConfig); +}; diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 9c25e7d..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,103 +0,0 @@ -/* eslint-disable no-undef */ -/* eslint-disable @typescript-eslint/no-var-requires */ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -//@ts-check -"use strict"; - -//@ts-check -/** @typedef {import('webpack').Configuration} WebpackConfig **/ - -const path = require("path"); - -/** @type WebpackConfig */ -const browserClientConfig = { - context: path.join(__dirname, "client"), - mode: "none", - target: "webworker", // web extensions run in a webworker context - entry: { - browserClientMain: "./src/browser/extension.ts", - }, - output: { - filename: "[name].js", - path: path.join(__dirname, "client", "dist"), - libraryTarget: "commonjs", - }, - resolve: { - mainFields: ["module", "main"], - extensions: [".ts", ".js"], // support ts-files and js-files - alias: {}, - fallback: { - path: require.resolve("path-browserify"), - }, - }, - module: { - rules: [ - { - test: /\.ts$/, - exclude: /node_modules/, - use: [ - { - loader: "ts-loader", - }, - ], - }, - ], - }, - externals: { - vscode: "commonjs vscode", // ignored because it doesn't exist - }, - performance: { - hints: false, - }, - devtool: "source-map", -}; - -/** @type WebpackConfig */ -const browserServerConfig = { - context: path.join(__dirname, "server"), - mode: "none", - target: "webworker", // web extensions run in a webworker context - entry: { - browserServerMain: "./src/browser/server.ts", - }, - output: { - filename: "[name].js", - path: path.join(__dirname, "server", "dist"), - libraryTarget: "var", - library: "serverExportVar", - }, - resolve: { - mainFields: ["module", "main"], - extensions: [".ts", ".js"], // support ts-files and js-files - alias: {}, - fallback: { - //path: require.resolve("path-browserify") - }, - }, - module: { - rules: [ - { - test: /\.ts$/, - exclude: /node_modules/, - use: [ - { - loader: "ts-loader", - }, - ], - }, - ], - }, - externals: { - vscode: "commonjs vscode", // ignored because it doesn't exist - }, - performance: { - hints: false, - }, - devtool: "source-map", -}; - -module.exports = [browserClientConfig, browserServerConfig]; From 6fdac01e47b87b9a5b6be3a1455174ba0dcbe8dd Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Fri, 25 Feb 2022 20:47:26 +0100 Subject: [PATCH 2/9] Update launch and tasks config --- .vscode/launch.json | 35 +++++++++++++++++++++++------------ .vscode/tasks.json | 19 +------------------ 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index b564042..c792802 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,25 @@ "version": "0.2.0", "configurations": [ { - "name": "Launch Client", + "name": "Launch Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + ], + "skipFiles": [ + "/**/*.js", + "**/node_modules/**/*.js" + ], + "smartStep": true, + "sourceMaps": true, + "outFiles": [ + "${workspaceFolder}/client/dist/**/*.js" + ] + }, + { + "name": "Launch Extension in Webworker", "type": "pwa-extensionHost", "debugWebWorkerHost": true, "request": "launch", @@ -14,12 +32,14 @@ "--extensionDevelopmentPath=${workspaceRoot}", "--extensionDevelopmentKind=web" ], + "smartStep": true, + "sourceMaps": true, "outFiles": [ - "${workspaceRoot}/client/dist/**/*.js" + "${workspaceRoot}/client/dist/web/**/*.js" ], "preLaunchTask": { "type": "npm", - "script": "watch-web" + "script": "compile" } }, { @@ -32,14 +52,5 @@ "${workspaceRoot}/server/dist/**/*.js" ] } - ], - "compounds": [ - { - "name": "Client + Server", - "configurations": [ - "Launch Client", - "Attach to Server" - ] - } ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 41394f9..47b9d12 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -5,7 +5,7 @@ "tasks": [ { "type": "npm", - "script": "compile-web", + "script": "compile", "group": "build", "presentation": { "panel": "dedicated", @@ -15,23 +15,6 @@ "$ts-webpack", "$tslint-webpack" ] - }, - { - "type": "npm", - "script": "watch-web", - "isBackground": true, - "group": { - "kind": "build", - "isDefault": true - }, - "presentation": { - "panel": "dedicated", - "reveal": "never" - }, - "problemMatcher": [ - "$ts-webpack-watch", - "$tslint-webpack-watch" - ] } ] } From bc42fc3ea96cbf2ca48af883ea73afbf6c28c633 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Fri, 25 Feb 2022 20:49:25 +0100 Subject: [PATCH 3/9] Add server for node extension mode --- server/src/browser/{server.ts => nativeServer.ts} | 0 server/src/node/nativeServer.ts | 9 +++++++++ 2 files changed, 9 insertions(+) rename server/src/browser/{server.ts => nativeServer.ts} (100%) create mode 100644 server/src/node/nativeServer.ts diff --git a/server/src/browser/server.ts b/server/src/browser/nativeServer.ts similarity index 100% rename from server/src/browser/server.ts rename to server/src/browser/nativeServer.ts diff --git a/server/src/node/nativeServer.ts b/server/src/node/nativeServer.ts new file mode 100644 index 0000000..0a2c3dd --- /dev/null +++ b/server/src/node/nativeServer.ts @@ -0,0 +1,9 @@ +import { createConnection } from "vscode-languageserver/node"; +import { GalaxyWorkflowLanguageServer } from "../server"; +import { NativeWorkflowLanguageService } from "../languageService"; + +const connection = createConnection(); + +const languageService = new NativeWorkflowLanguageService(); +const server = new GalaxyWorkflowLanguageServer(connection, languageService); +server.start(); From 18f1e65fb12a6ce3c5fe1840a58af67a140f45b0 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Fri, 25 Feb 2022 20:52:13 +0100 Subject: [PATCH 4/9] Refactor extension to use CommonLanguageClient abstraction --- client/src/commands/common.ts | 8 ++++---- client/src/commands/setup.ts | 4 ++-- client/src/providers/cleanWorkflowDocumentProvider.ts | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/src/commands/common.ts b/client/src/commands/common.ts index 246abb4..3f4d53a 100644 --- a/client/src/commands/common.ts +++ b/client/src/commands/common.ts @@ -1,5 +1,5 @@ import { commands, Disposable } from "vscode"; -import { LanguageClient } from "vscode-languageclient/browser"; +import { CommonLanguageClient } from "vscode-languageclient"; /** * Gets the fully-qualified identifier of the command by prefixing @@ -17,9 +17,9 @@ export function getCommandFullIdentifier(command: string) { */ export abstract class CommandContext { /** Allows to access language features. */ - protected client: LanguageClient; + protected client: CommonLanguageClient; - constructor(client: LanguageClient) { + constructor(client: CommonLanguageClient) { this.client = client; } } @@ -30,7 +30,7 @@ export abstract class CommandContext { */ export abstract class CustomCommand extends CommandContext { abstract readonly identifier: string; - constructor(client: LanguageClient) { + constructor(client: CommonLanguageClient) { super(client); } diff --git a/client/src/commands/setup.ts b/client/src/commands/setup.ts index a423f0e..86f3e55 100644 --- a/client/src/commands/setup.ts +++ b/client/src/commands/setup.ts @@ -1,5 +1,5 @@ import { ExtensionContext } from "vscode"; -import { LanguageClient } from "vscode-languageclient/browser"; +import { CommonLanguageClient } from "vscode-languageclient"; import { CompareCleanWithWorkflowsCommand } from "./compareCleanWith"; import { CompareCleanWorkflowsCommand } from "./compareCleanWorkflows"; import { PreviewCleanWorkflowCommand } from "./previewCleanWorkflow"; @@ -9,7 +9,7 @@ import { PreviewCleanWorkflowCommand } from "./previewCleanWorkflow"; * @param context The extension context * @param client The language client */ -export function setupCommands(context: ExtensionContext, client: LanguageClient) { +export function setupCommands(context: ExtensionContext, client: CommonLanguageClient) { context.subscriptions.push(new PreviewCleanWorkflowCommand(client).register()); context.subscriptions.push(new CompareCleanWorkflowsCommand(client).register()); context.subscriptions.push(new CompareCleanWithWorkflowsCommand(client).register()); diff --git a/client/src/providers/cleanWorkflowDocumentProvider.ts b/client/src/providers/cleanWorkflowDocumentProvider.ts index 15ed846..212f69d 100644 --- a/client/src/providers/cleanWorkflowDocumentProvider.ts +++ b/client/src/providers/cleanWorkflowDocumentProvider.ts @@ -1,5 +1,5 @@ import { EventEmitter, ExtensionContext, TextDocumentContentProvider, Uri, workspace } from "vscode"; -import { LanguageClient, RequestType } from "vscode-languageclient/browser"; +import { CommonLanguageClient, RequestType } from "vscode-languageclient"; import { Constants, LSRequestIdentifiers } from "../constants"; import { getWorkspaceScheme, replaceUriScheme } from "../utils"; @@ -19,14 +19,14 @@ namespace CleanWorkflowDocumentRequest { } export class CleanWorkflowDocumentProvider implements TextDocumentContentProvider { - public static register(context: ExtensionContext, client: LanguageClient) { + public static register(context: ExtensionContext, client: CommonLanguageClient) { const provider = new CleanWorkflowDocumentProvider(client); context.subscriptions.push( workspace.registerTextDocumentContentProvider(Constants.CLEAN_WORKFLOW_DOCUMENT_SCHEME, provider) ); } - constructor(private readonly languageClient: LanguageClient) {} + constructor(private readonly languageClient: CommonLanguageClient) {} onDidChangeEmitter = new EventEmitter(); onDidChange = this.onDidChangeEmitter.event; From ee36dd9f2ae37ac6431c3be1d7fe45f7ef8f3b8f Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Fri, 25 Feb 2022 20:53:22 +0100 Subject: [PATCH 5/9] Add node extension entry point --- client/src/browser/extension.ts | 2 +- client/src/common.ts | 14 +++++++ client/src/extension.ts | 67 +++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 client/src/common.ts create mode 100644 client/src/extension.ts diff --git a/client/src/browser/extension.ts b/client/src/browser/extension.ts index 40257cb..a07c97c 100644 --- a/client/src/browser/extension.ts +++ b/client/src/browser/extension.ts @@ -45,7 +45,7 @@ function createWorkerLanguageClient(context: ExtensionContext, clientOptions: La function createServerWorker(context: ExtensionContext) { // The worker main file implements the language server. - const serverMain = Uri.joinPath(context.extensionUri, "server/dist/browserServerMain.js"); + const serverMain = Uri.joinPath(context.extensionUri, "server/dist/web/nativeServer.js"); const worker = new Worker(serverMain.toString()); return worker; } diff --git a/client/src/common.ts b/client/src/common.ts new file mode 100644 index 0000000..4227e99 --- /dev/null +++ b/client/src/common.ts @@ -0,0 +1,14 @@ +import { LanguageClientOptions } from "vscode-languageclient"; +import { Constants } from "./constants"; + +export function buildLanguageClientOptions() { + const documentSelector = [{ language: Constants.NATIVE_WORKFLOW_LANGUAGE_ID }]; + + // Options to control the language client + const clientOptions: LanguageClientOptions = { + documentSelector, + synchronize: {}, + initializationOptions: {}, + }; + return clientOptions; +} diff --git a/client/src/extension.ts b/client/src/extension.ts new file mode 100644 index 0000000..260a738 --- /dev/null +++ b/client/src/extension.ts @@ -0,0 +1,67 @@ +import * as path from "path"; +import { ExtensionContext } from "vscode"; +import { LanguageClientOptions } from "vscode-languageclient"; +import { LanguageClient, ServerOptions, TransportKind } from "vscode-languageclient/node"; +import { setupCommands } from "./commands/setup"; +import { buildLanguageClientOptions } from "./common"; +import { CleanWorkflowDocumentProvider } from "./providers/cleanWorkflowDocumentProvider"; + +export function activate(context: ExtensionContext) { + console.log(`${context.extension.id} is now active in the web extension host.`); + + const client = startLanguageClient(context); + + setupProviders(context, client); + + setupCommands(context, client); +} + +export function deactivate() {} + +function startLanguageClient(context: ExtensionContext) { + const clientOptions: LanguageClientOptions = buildLanguageClientOptions(); + + // The server is implemented in node + const serverModule = context.asAbsolutePath(path.join("server", "dist", "nativeServer.js")); + // The debug options for the server + // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging + const debugOptions = { execArgv: ["--nolazy", "--inspect=6009"] }; + + // If the extension is launched in debug mode then the debug server options are used + // Otherwise the run options are used + const serverOptions: ServerOptions = { + run: { module: serverModule, transport: TransportKind.ipc }, + debug: { + module: serverModule, + transport: TransportKind.ipc, + options: debugOptions, + }, + }; + + const client = createLanguageClient(context, serverOptions, clientOptions); + + const disposable = client.start(); + context.subscriptions.push(disposable); + + client.onReady().then(() => { + console.log(`${context.extension.id} server is ready.`); + }); + return client; +} + +function createLanguageClient( + context: ExtensionContext, + serverOptions: ServerOptions, + clientOptions: LanguageClientOptions +) { + return new LanguageClient( + "galaxy-workflow-language-client-native", + "Galaxy Workflows LS", + serverOptions, + clientOptions + ); +} + +function setupProviders(context: ExtensionContext, client: LanguageClient) { + CleanWorkflowDocumentProvider.register(context, client); +} From 62ab31b01a45f3e6a7ecbd41be0f37d55db0b3ad Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Fri, 25 Feb 2022 20:54:25 +0100 Subject: [PATCH 6/9] Update launch instructions in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dc53f11..11125d5 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,6 @@ TBA ``` - Build ```sh - npm run compile-web + npm run compile ``` -- Run the `Launch Client` configuration from the `Run and Debug` action bar (or press F5). +- Run the `Launch Extension` configuration from the `Run and Debug` action bar (or press F5). From d2028fc00ea404206379ef944facfe23a888884a Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Sat, 26 Feb 2022 13:45:37 +0100 Subject: [PATCH 7/9] Refactor extension initialization --- client/src/browser/extension.ts | 29 ++++---------------------- client/src/common.ts | 14 ++++++++++++- client/src/extension.ts | 36 +++++++++++++++------------------ 3 files changed, 33 insertions(+), 46 deletions(-) diff --git a/client/src/browser/extension.ts b/client/src/browser/extension.ts index a07c97c..ab1788f 100644 --- a/client/src/browser/extension.ts +++ b/client/src/browser/extension.ts @@ -1,31 +1,20 @@ import { ExtensionContext, Uri } from "vscode"; import { LanguageClientOptions } from "vscode-languageclient"; import { LanguageClient } from "vscode-languageclient/browser"; -import { setupCommands } from "../commands/setup"; -import { Constants } from "../constants"; -import { CleanWorkflowDocumentProvider } from "../providers/cleanWorkflowDocumentProvider"; +import { buildLanguageClientOptions, initExtension } from "../common"; export function activate(context: ExtensionContext) { console.log(`${context.extension.id} is now active in the web extension host.`); const client = startLanguageClient(context); - setupProviders(context, client); - - setupCommands(context, client); + initExtension(context, client); } export function deactivate() {} function startLanguageClient(context: ExtensionContext) { - const documentSelector = [{ language: Constants.NATIVE_WORKFLOW_LANGUAGE_ID }]; - - // Options to control the language client - const clientOptions: LanguageClientOptions = { - documentSelector, - synchronize: {}, - initializationOptions: {}, - }; + const clientOptions: LanguageClientOptions = buildLanguageClientOptions(); const client = createWorkerLanguageClient(context, clientOptions); @@ -39,17 +28,7 @@ function startLanguageClient(context: ExtensionContext) { } function createWorkerLanguageClient(context: ExtensionContext, clientOptions: LanguageClientOptions) { - const worker = createServerWorker(context); - return new LanguageClient("galaxy-workflow-language-client-native", "Galaxy Workflows LS", clientOptions, worker); -} - -function createServerWorker(context: ExtensionContext) { - // The worker main file implements the language server. const serverMain = Uri.joinPath(context.extensionUri, "server/dist/web/nativeServer.js"); const worker = new Worker(serverMain.toString()); - return worker; -} - -function setupProviders(context: ExtensionContext, client: LanguageClient) { - CleanWorkflowDocumentProvider.register(context, client); + return new LanguageClient("galaxy-workflow-language-client-native", "Galaxy Workflows LS", clientOptions, worker); } diff --git a/client/src/common.ts b/client/src/common.ts index 4227e99..24f5d45 100644 --- a/client/src/common.ts +++ b/client/src/common.ts @@ -1,5 +1,8 @@ -import { LanguageClientOptions } from "vscode-languageclient"; +import { ExtensionContext } from "vscode"; +import { CommonLanguageClient, LanguageClientOptions } from "vscode-languageclient"; +import { setupCommands } from "./commands/setup"; import { Constants } from "./constants"; +import { CleanWorkflowDocumentProvider } from "./providers/cleanWorkflowDocumentProvider"; export function buildLanguageClientOptions() { const documentSelector = [{ language: Constants.NATIVE_WORKFLOW_LANGUAGE_ID }]; @@ -12,3 +15,12 @@ export function buildLanguageClientOptions() { }; return clientOptions; } + +export function initExtension(context: ExtensionContext, client: CommonLanguageClient) { + setupProviders(context, client); + setupCommands(context, client); +} + +function setupProviders(context: ExtensionContext, client: CommonLanguageClient) { + CleanWorkflowDocumentProvider.register(context, client); +} diff --git a/client/src/extension.ts b/client/src/extension.ts index 260a738..9427abc 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -2,25 +2,34 @@ import * as path from "path"; import { ExtensionContext } from "vscode"; import { LanguageClientOptions } from "vscode-languageclient"; import { LanguageClient, ServerOptions, TransportKind } from "vscode-languageclient/node"; -import { setupCommands } from "./commands/setup"; -import { buildLanguageClientOptions } from "./common"; -import { CleanWorkflowDocumentProvider } from "./providers/cleanWorkflowDocumentProvider"; +import { buildLanguageClientOptions, initExtension } from "./common"; export function activate(context: ExtensionContext) { console.log(`${context.extension.id} is now active in the web extension host.`); const client = startLanguageClient(context); - setupProviders(context, client); - - setupCommands(context, client); + initExtension(context, client); } export function deactivate() {} function startLanguageClient(context: ExtensionContext) { const clientOptions: LanguageClientOptions = buildLanguageClientOptions(); + const serverOptions: ServerOptions = buildServerOptions(context); + + const client = createLanguageClient(context, serverOptions, clientOptions); + + const disposable = client.start(); + context.subscriptions.push(disposable); + + client.onReady().then(() => { + console.log(`${context.extension.id} server is ready.`); + }); + return client; +} +function buildServerOptions(context: ExtensionContext) { // The server is implemented in node const serverModule = context.asAbsolutePath(path.join("server", "dist", "nativeServer.js")); // The debug options for the server @@ -37,16 +46,7 @@ function startLanguageClient(context: ExtensionContext) { options: debugOptions, }, }; - - const client = createLanguageClient(context, serverOptions, clientOptions); - - const disposable = client.start(); - context.subscriptions.push(disposable); - - client.onReady().then(() => { - console.log(`${context.extension.id} server is ready.`); - }); - return client; + return serverOptions; } function createLanguageClient( @@ -61,7 +61,3 @@ function createLanguageClient( clientOptions ); } - -function setupProviders(context: ExtensionContext, client: LanguageClient) { - CleanWorkflowDocumentProvider.register(context, client); -} From 5c74e62371820c503e9af030d2c8d8e61de74da0 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Thu, 3 Mar 2022 20:24:59 +0100 Subject: [PATCH 8/9] Fix Unbound break point when debugging in Node --- .vscode/launch.json | 14 ++++++++------ client/tsconfig.json | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c792802..057a1b1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,19 +9,21 @@ "name": "Launch Extension", "type": "extensionHost", "request": "launch", - "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}", ], - "skipFiles": [ - "/**/*.js", - "**/node_modules/**/*.js" - ], "smartStep": true, "sourceMaps": true, "outFiles": [ "${workspaceFolder}/client/dist/**/*.js" - ] + ], + "preLaunchTask": { + "type": "npm", + "script": "compile" + }, + "sourceMapPathOverrides": { + "webpack://?:*/*": "${workspaceFolder}/client/*" + } }, { "name": "Launch Extension in Webworker", diff --git a/client/tsconfig.json b/client/tsconfig.json index 7916cbc..3a529d0 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -7,7 +7,7 @@ "WebWorker" ], "rootDir": "src", - "sourceMap": true + "sourceMap": true, }, "include": [ "src" From f3f428e837905c6279ed0b6b97671d75baaf742f Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Thu, 3 Mar 2022 20:35:57 +0100 Subject: [PATCH 9/9] Refactor common activation --- client/src/browser/extension.ts | 23 ++++------------------ client/src/common.ts | 7 +++++++ client/src/extension.ts | 35 ++++++++------------------------- 3 files changed, 19 insertions(+), 46 deletions(-) diff --git a/client/src/browser/extension.ts b/client/src/browser/extension.ts index ab1788f..130ea59 100644 --- a/client/src/browser/extension.ts +++ b/client/src/browser/extension.ts @@ -4,31 +4,16 @@ import { LanguageClient } from "vscode-languageclient/browser"; import { buildLanguageClientOptions, initExtension } from "../common"; export function activate(context: ExtensionContext) { - console.log(`${context.extension.id} is now active in the web extension host.`); - - const client = startLanguageClient(context); + const client = buildWebLanguageClient(context); initExtension(context, client); } export function deactivate() {} -function startLanguageClient(context: ExtensionContext) { +function buildWebLanguageClient(context: ExtensionContext) { const clientOptions: LanguageClientOptions = buildLanguageClientOptions(); - - const client = createWorkerLanguageClient(context, clientOptions); - - const disposable = client.start(); - context.subscriptions.push(disposable); - - client.onReady().then(() => { - console.log(`${context.extension.id} server is ready.`); - }); - return client; -} - -function createWorkerLanguageClient(context: ExtensionContext, clientOptions: LanguageClientOptions) { - const serverMain = Uri.joinPath(context.extensionUri, "server/dist/web/nativeServer.js"); - const worker = new Worker(serverMain.toString()); + const serverPath = Uri.joinPath(context.extensionUri, "server/dist/web/nativeServer.js"); + const worker = new Worker(serverPath.toString()); return new LanguageClient("galaxy-workflow-language-client-native", "Galaxy Workflows LS", clientOptions, worker); } diff --git a/client/src/common.ts b/client/src/common.ts index 24f5d45..5b37e50 100644 --- a/client/src/common.ts +++ b/client/src/common.ts @@ -19,6 +19,13 @@ export function buildLanguageClientOptions() { export function initExtension(context: ExtensionContext, client: CommonLanguageClient) { setupProviders(context, client); setupCommands(context, client); + + const disposable = client.start(); + context.subscriptions.push(disposable); + + client.onReady().then(() => { + console.log(`${context.extension.id} server is ready.`); + }); } function setupProviders(context: ExtensionContext, client: CommonLanguageClient) { diff --git a/client/src/extension.ts b/client/src/extension.ts index 9427abc..974a9d6 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -5,28 +5,22 @@ import { LanguageClient, ServerOptions, TransportKind } from "vscode-languagecli import { buildLanguageClientOptions, initExtension } from "./common"; export function activate(context: ExtensionContext) { - console.log(`${context.extension.id} is now active in the web extension host.`); - - const client = startLanguageClient(context); + const client = buildLanguageClient(context); initExtension(context, client); } export function deactivate() {} -function startLanguageClient(context: ExtensionContext) { +function buildLanguageClient(context: ExtensionContext) { const clientOptions: LanguageClientOptions = buildLanguageClientOptions(); const serverOptions: ServerOptions = buildServerOptions(context); - - const client = createLanguageClient(context, serverOptions, clientOptions); - - const disposable = client.start(); - context.subscriptions.push(disposable); - - client.onReady().then(() => { - console.log(`${context.extension.id} server is ready.`); - }); - return client; + return new LanguageClient( + "galaxy-workflow-language-client-native", + "Galaxy Workflows LS", + serverOptions, + clientOptions + ); } function buildServerOptions(context: ExtensionContext) { @@ -48,16 +42,3 @@ function buildServerOptions(context: ExtensionContext) { }; return serverOptions; } - -function createLanguageClient( - context: ExtensionContext, - serverOptions: ServerOptions, - clientOptions: LanguageClientOptions -) { - return new LanguageClient( - "galaxy-workflow-language-client-native", - "Galaxy Workflows LS", - serverOptions, - clientOptions - ); -}