Skip to content

Commit

Permalink
Unify python and json language server. Extract common function. Make …
Browse files Browse the repository at this point in the history
…both external
  • Loading branch information
kaisalmen committed Oct 11, 2023
1 parent 5b9e70f commit fe747da
Show file tree
Hide file tree
Showing 16 changed files with 127 additions and 124 deletions.
3 changes: 2 additions & 1 deletion .gitpod.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
ports:
- port: 3000
- port: 30000
- port: 30001
- port: 8080
tasks:
- before: bash scripts/auth.sh
Expand Down
2 changes: 1 addition & 1 deletion packages/examples/src/browser/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { languages, workspace, TextDocument as VsCodeTextDocument } from 'vscode
import { getLanguageService, TextDocument } from 'vscode-json-languageservice';
import { createConverter as createCodeConverter } from 'vscode-languageclient/lib/common/codeConverter.js';
import { createConverter as createProtocolConverter } from 'vscode-languageclient/lib/common/protocolConverter.js';
import { createDefaultJsonContent, createJsonEditor, performInit } from '../common.js';
import { createDefaultJsonContent, createJsonEditor, performInit } from '../common/client-commons.js';
import '@codingame/monaco-vscode-theme-defaults-default-extension';
import '@codingame/monaco-vscode-json-default-extension';
import { buildWorkerDefinition } from 'monaco-editor-workers';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ export const createJsonEditor = async (config: {
lightbulb: {
enabled: true
},
automaticLayout: true
automaticLayout: true,
wordBasedSuggestions: false
});

const result = {
Expand Down
82 changes: 82 additions & 0 deletions packages/examples/src/common/server-commons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) 2018-2022 TypeFox GmbH (http://www.typefox.io). All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import { resolve } from 'path';
import { WebSocketServer } from 'ws';
import { IncomingMessage, Server } from 'http';
import { URL } from 'url';
import { Socket } from 'net';
import { IWebSocket, WebSocketMessageReader, WebSocketMessageWriter } from 'vscode-ws-jsonrpc';
import { createConnection, createServerProcess, forward } from 'vscode-ws-jsonrpc/server';
import { Message, InitializeRequest, InitializeParams } from 'vscode-languageserver';

/**
* start the language server inside the current process
*/
export const launchLanguageServer = (serverName: string, socket: IWebSocket, baseDir: string, relativeDir: string) => {
// start the language server as an external process
const ls = resolve(baseDir, relativeDir);
const serverConnection = createServerProcess(serverName, 'node', [ls, '--stdio']);

const reader = new WebSocketMessageReader(socket);
const writer = new WebSocketMessageWriter(socket);
const socketConnection = createConnection(reader, writer, () => socket.dispose());
if (serverConnection) {
forward(socketConnection, serverConnection, message => {
if (Message.isRequest(message)) {
console.log(`${serverName} Server received:`);
console.log(message);
if (message.method === InitializeRequest.type.method) {
const initializeParams = message.params as InitializeParams;
initializeParams.processId = process.pid;
}
}
if (Message.isResponse(message)) {
console.log(`${serverName} Server sent:`);
console.log(message);
}
return message;
});
}
};

export const upgradeWsServer = (config: {
serverName: string,
pathName: string,
server: Server,
wss: WebSocketServer,
baseDir: string,
relativeDir: string
}) => {
config.server.on('upgrade', (request: IncomingMessage, socket: Socket, head: Buffer) => {
const baseURL = `http://${request.headers.host}/`;
const pathName = request.url ? new URL(request.url, baseURL).pathname : undefined;
if (pathName === config.pathName) {
config.wss.handleUpgrade(request, socket, head, webSocket => {
const socket: IWebSocket = {
send: content => webSocket.send(content, error => {
if (error) {
throw error;
}
}),
onMessage: cb => webSocket.on('message', (data) => {
console.log(data.toString());
cb(data);
}),
onError: cb => webSocket.on('error', cb),
onClose: cb => webSocket.on('close', cb),
dispose: () => webSocket.close()
};
// launch the server when the web socket is opened
if (webSocket.readyState === webSocket.OPEN) {
launchLanguageServer(config.serverName, socket, config.baseDir, config.relativeDir);
} else {
webSocket.on('open', () => {
launchLanguageServer(config.serverName, socket, config.baseDir, config.relativeDir);
});
}
});
}
});
};
2 changes: 1 addition & 1 deletion packages/examples/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

export * from './common.js';
export * from './common/client-commons.js';
export * from './browser/main.js';
export * from './json/client/main.js';
export * from './langium/statemachineClient.js';
Expand Down
4 changes: 2 additions & 2 deletions packages/examples/src/json/client/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import { createDefaultJsonContent, createJsonEditor, createUrl, createWebSocketAndStartClient, performInit } from '../../common.js';
import { createDefaultJsonContent, createJsonEditor, createUrl, createWebSocketAndStartClient, performInit } from '../../common/client-commons.js';
import { buildWorkerDefinition } from 'monaco-editor-workers';
buildWorkerDefinition('../../node_modules/monaco-editor-workers/dist/workers/', new URL('', window.location.href).href, false);

Expand All @@ -15,6 +15,6 @@ export const startJsonClient = async () => {
content: createDefaultJsonContent()
});

const url = createUrl('localhost', 3000, '/sampleServer');
const url = createUrl('localhost', 30000, '/sampleServer');
createWebSocketAndStartClient(url);
};
6 changes: 5 additions & 1 deletion packages/examples/src/json/server/direct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
* Copyright (c) 2018-2022 TypeFox GmbH (http://www.typefox.io). All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import { resolve } from 'path';
import { runJsonServer } from './main.js';
import { getLocalDirectory } from '../../utils/fs-utils.js';

runJsonServer();
const baseDir = resolve(getLocalDirectory(import.meta.url));
const relativeDir = '../../../dist/json/server/json-server.js';
runJsonServer(baseDir, relativeDir);
6 changes: 5 additions & 1 deletion packages/examples/src/json/server/json-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { readFile } from 'fs';
import requestLight from 'request-light';
import * as URI from 'vscode-uri';
import 'vscode-ws-jsonrpc';
import { _Connection, TextDocuments, DocumentSymbolParams } from 'vscode-languageserver/lib/node/main.js';
import { createConnection, _Connection, TextDocuments, DocumentSymbolParams, ProposedFeatures } from 'vscode-languageserver/lib/node/main.js';
import {
Diagnostic, Command, CompletionList, CompletionItem, Hover,
SymbolInformation, TextEdit, FoldingRange, ColorInformation, ColorPresentation
Expand Down Expand Up @@ -256,3 +256,7 @@ export class JsonServer {
return this.jsonService.parseJSONDocument(document);
}
}

const connection = createConnection(ProposedFeatures.all);
const ls = new JsonServer(connection);
ls.start();
58 changes: 11 additions & 47 deletions packages/examples/src/json/server/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import { WebSocketServer } from 'ws';
import { IncomingMessage } from 'http';
import { URL } from 'url';
import { Socket } from 'net';
import { Server } from 'http';
import express from 'express';
import { IWebSocket, WebSocketMessageReader, WebSocketMessageWriter } from 'vscode-ws-jsonrpc';
import { createConnection } from 'vscode-languageserver/lib/node/main.js';
import { getLocalDirectory } from '../../utils/fs-utils.js';
import { JsonServer } from './json-server.js';
import { upgradeWsServer } from '../../common/server-commons.js';

/**
* start the language server inside the current process
*/
const launchLanguageServer = (socket: IWebSocket): JsonServer => {
const reader = new WebSocketMessageReader(socket);
const writer = new WebSocketMessageWriter(socket);
const connection = createConnection(reader, writer);
const server = new JsonServer(connection);
server.start();
return server;
};

export const runJsonServer = () => {
export const runJsonServer = (baseDir: string, relativeDir: string) => {
process.on('uncaughtException', function(err: any) {
console.error('Uncaught Exception: ', err.toString());
if (err.stack) {
Expand All @@ -38,38 +22,18 @@ export const runJsonServer = () => {
const dir = getLocalDirectory(import.meta.url);
app.use(express.static(dir));
// start the server
const server = app.listen(3000);
const server: Server = app.listen(30000);
// create the web socket
const wss = new WebSocketServer({
noServer: true,
perMessageDeflate: false
});
server.on('upgrade', (request: IncomingMessage, socket: Socket, head: Buffer) => {
const baseURL = `http://${request.headers.host}/`;
const pathname = request.url ? new URL(request.url, baseURL).pathname : undefined;
if (pathname === '/sampleServer') {
wss.handleUpgrade(request, socket, head, webSocket => {
const socket: IWebSocket = {
send: content => webSocket.send(content, error => {
if (error) {
throw error;
}
}),
onMessage: cb => webSocket.on('message', (data) => {
console.log(data.toString());
cb(data);
}),
onError: cb => webSocket.on('error', cb),
onClose: cb => webSocket.on('close', cb),
dispose: () => webSocket.close()
};
// launch the server when the web socket is opened
if (webSocket.readyState === webSocket.OPEN) {
launchLanguageServer(socket);
} else {
webSocket.on('open', () => launchLanguageServer(socket));
}
});
}
upgradeWsServer({
serverName: 'JSON',
pathName: '/sampleServer',
server,
wss,
baseDir,
relativeDir
});
};
1 change: 1 addition & 0 deletions packages/examples/src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

export * from './common/server-commons.js';
export * from './json/server/json-server.js';
export * from './json/server/main.js';
export * from './python/server/main.js';
Expand Down
4 changes: 2 additions & 2 deletions packages/examples/src/python/client/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { CloseAction, ErrorAction, MessageTransports } from 'vscode-languageclie
import { WebSocketMessageReader, WebSocketMessageWriter, toSocket } from 'vscode-ws-jsonrpc';
import { RegisteredFileSystemProvider, registerFileSystemOverlay, RegisteredMemoryFile } from '@codingame/monaco-vscode-files-service-override';
import { Uri } from 'vscode';
import { createUrl } from '../../common.js';
import { createUrl } from '../../common/client-commons.js';

import { buildWorkerDefinition } from 'monaco-editor-workers';
buildWorkerDefinition('../../../node_modules/monaco-editor-workers/dist/workers/', new URL('', window.location.href).href, false);
Expand Down Expand Up @@ -140,7 +140,7 @@ export const startPythonClient = async () => {
registerFileSystemOverlay(1, fileSystemProvider);

// create the web socket and configure to start the language client on open, can add extra parameters to the url if needed.
createWebSocket(createUrl('localhost', 30000, '/pyright', {
createWebSocket(createUrl('localhost', 30001, '/pyright', {
// Used to parse an auth token or additional parameters such as import IDs to the language server
authorization: 'UserAuth'
// By commenting above line out and commenting below line in, connection to language server will be denied.
Expand Down
72 changes: 9 additions & 63 deletions packages/examples/src/python/server/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,9 @@
import { WebSocketServer } from 'ws';
import { IncomingMessage } from 'http';
import { URL } from 'url';
import { Socket } from 'net';
import express from 'express';
import { resolve } from 'path';
import { IWebSocket, WebSocketMessageReader, WebSocketMessageWriter } from 'vscode-ws-jsonrpc';
import { createConnection, createServerProcess, forward } from 'vscode-ws-jsonrpc/server';
import { Message, InitializeRequest, InitializeParams } from 'vscode-languageserver';
import { getLocalDirectory } from '../../utils/fs-utils.js';

const launchLanguageServer = (socket: IWebSocket, baseDir: string, relativeDir: string) => {
const serverName = 'PYRIGHT';
// start the language server as an external process
const ls = resolve(baseDir, relativeDir);
const serverConnection = createServerProcess(serverName, 'node', [ls, '--stdio']);

const reader = new WebSocketMessageReader(socket);
const writer = new WebSocketMessageWriter(socket);
const socketConnection = createConnection(reader, writer, () => socket.dispose());
if (serverConnection) {
forward(socketConnection, serverConnection, message => {
if (Message.isRequest(message)) {
console.log(`${serverName} Server received:`);
console.log(message);
if (message.method === InitializeRequest.type.method) {
const initializeParams = message.params as InitializeParams;
initializeParams.processId = process.pid;
}
}
if (Message.isResponse(message)) {
console.log(`${serverName} Server sent:`);
console.log(message);
}
return message;
});
}
};
import { upgradeWsServer } from '../../common/server-commons.js';

export const runPythonServer = (baseDir: string, relativeDir: string) => {
process.on('uncaughtException', function(err: any) {
Expand All @@ -55,7 +23,7 @@ export const runPythonServer = (baseDir: string, relativeDir: string) => {
const dir = getLocalDirectory(import.meta.url);
app.use(express.static(dir));
// start the server
const server = app.listen(30000);
const server = app.listen(30001);
// create the web socket
const wss = new WebSocketServer({
noServer: true,
Expand All @@ -76,34 +44,12 @@ export const runPythonServer = (baseDir: string, relativeDir: string) => {
}
}
});

server.on('upgrade', (request: IncomingMessage, socket: Socket, head: Buffer) => {
const baseURL = `http://${request.headers.host}/`;
const pathname = request.url ? new URL(request.url, baseURL).pathname : undefined;
if (pathname === '/pyright') {
wss.handleUpgrade(request, socket, head, webSocket => {
const socket: IWebSocket = {
send: content => webSocket.send(content, error => {
if (error) {
throw error;
}
}),
onMessage: cb => webSocket.on('message', (data) => {
cb(data);
}),
onError: cb => webSocket.on('error', cb),
onClose: cb => webSocket.on('close', cb),
dispose: () => webSocket.close()
};
// launch the server when the web socket is opened
if (webSocket.readyState === webSocket.OPEN) {
launchLanguageServer(socket, baseDir, relativeDir);
} else {
webSocket.on('open', () => {
launchLanguageServer(socket, baseDir, relativeDir);
});
}
});
}
upgradeWsServer({
serverName: 'PYRIGHT',
pathName: '/pyright',
server,
wss,
baseDir,
relativeDir
});
};
2 changes: 1 addition & 1 deletion packages/examples/src/react/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright (c) 2018-2022 TypeFox GmbH (http://www.typefox.io). All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import { createJsonEditor, createUrl, createWebSocketAndStartClient, performInit } from '../common.js';
import { createJsonEditor, createUrl, createWebSocketAndStartClient, performInit } from '../common/client-commons.js';
import { editor } from 'monaco-editor';
import React, { createRef, useEffect, useMemo, useRef } from 'react';

Expand Down
2 changes: 1 addition & 1 deletion packages/examples/src/react/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ export const startReactJsonClient = () => {
defaultCode={defaultCode}
hostname={'localhost'}
path={'/sampleServer'}
port={3000} />);
port={30000} />);
};
2 changes: 1 addition & 1 deletion packages/verify/vite/src/client/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const start = async () => {
});

// create the web socket
const url = createUrl('localhost', 3000, '/sampleServer');
const url = createUrl('localhost', 30000, '/sampleServer');
createWebSocketAndStartClient(url);
};

Expand Down
2 changes: 1 addition & 1 deletion packages/verify/webpack/src/client/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const start = async () => {
});

// create the web socket
const url = createUrl('localhost', 3000, '/sampleServer');
const url = createUrl('localhost', 30000, '/sampleServer');
createWebSocketAndStartClient(url);
};

Expand Down

0 comments on commit fe747da

Please sign in to comment.