Как построить протокол языкового сервера в VSCode с помощью кода Java на стороне сервера? - PullRequest
0 голосов
/ 03 декабря 2018

Описание: Я пытаюсь создать расширение для VSCode, используя протокол клиент-сервер.На стороне сервера, я положил .jar файл, который включает в себя код Java.Он определяет структуру функции в BNF и анализирует ее.После этого он возвращает ошибки синтаксиса функции, которая присваивается системным символам, символам и т. Д.

Внутри сервера находится файл .jar.Таким образом, цель состоит в том, чтобы получить доступ к этому файлу и обеспечить соединение со стороной клиента.

Кроме того, другая вещь - ошибка, когда я отлаживаю код ниже;

Debugger listening on ws://127.0.0.1:7786/4d1a23b8-cfaf-4319-9764-b15a82582293
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
internal/modules/cjs/loader.js:582
    throw err;
    ^
Error: Cannot find module 'vscode'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:580:15)
    at Function.Module._load (internal/modules/cjs/loader.js:506:25)
    at Module.require (internal/modules/cjs/loader.js:636:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (/home/unit/Desktop/vscode-LSP-java-example/client/out/src/extension.js:11:18)
    at Module._compile (internal/modules/cjs/loader.js:685:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
    at Function.Module._load (internal/modules/cjs/loader.js:529:3)
Waiting for the debugger to disconnect...
Error: Cannot find module 'vscode'
loader.js:580
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:580:15)
    at Function.Module._load (internal/modules/cjs/loader.js:506:25)
    at Module.require (internal/modules/cjs/loader.js:636:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (/home/unit/Desktop/vscode-LSP-java-example/client/src/extension.ts:12:1)
    at Module._compile (internal/modules/cjs/loader.js:685:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
    at Function.Module._load (internal/modules/cjs/loader.js:529:3)

, когда я пыталсячтобы понять, что происходит внутри, многие говорят, что это может зависеть от версии Vscode или библиотек, которые я использовал.Но я не мог это исправить.

Если кто-то знает, в чем суть, которую я здесь упускаю, я буду признателен за это.

extension.ts file is;

import * as fs from "fs"
import * as path from 'path';
import * as net from 'net';
import * as child_process from "child_process";

import { workspace, Disposable, ExtensionContext } from 'vscode';
import { LanguageClient, LanguageClientOptions, SettingMonitor, StreamInfo } from 'vscode-languageclient';

export function activate(context: ExtensionContext) {

    function createServer(): Promise<StreamInfo> {
        return new Promise((resolve, reject) => {
            var server = net.createServer((socket) => {
                console.log("Creating server");

                resolve({
                    reader: socket,
                    writer: socket
                });

                socket.on('end', () => console.log("Disconnected"));
            }).on('error', (err) => {
                // handle errors here
                throw err;
            });

            let javaExecutablePath = findJavaExecutable('java');

            // grab a random port.
            server.listen(() => {
                // Start the child java process
                let options = { cwd: workspace.rootPath };

                let args = [
                    '-jar',
                    path.resolve(context.extensionPath, '..', 'server', 'eclipse.jar'),
                    server.address().toString()
                ]

                let process = child_process.spawn(javaExecutablePath, args, options);

                // Send raw output to a file
                if (!fs.existsSync(context.storagePath))
                    fs.mkdirSync(context.storagePath);

                let logFile = context.storagePath + '/vscode-lsp-java-example.log';
                let logStream = fs.createWriteStream(logFile, { flags: 'w' });

                process.stdout.pipe(logStream);
                process.stderr.pipe(logStream);

                console.log(`Storing log in '${logFile}'`);
            });
        });
    };

    // Options to control the language client
    let clientOptions: LanguageClientOptions = {
        // Register the server for plain text documents
        documentSelector: ['plaintext'],
        synchronize: {
            // Synchronize the setting section 'languageServerExample' to the server
            configurationSection: 'languageServerExample',
            // Notify the server about file changes to '.clientrc files contain in the workspace
            fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
        }
    }

    // Create the language client and start the client.
    let disposable = new LanguageClient('languageServerExample', 'Language Server Example', createServer, clientOptions).start();

    // Push the disposable to the context's subscriptions so that the 
    // client can be deactivated on extension deactivation
    context.subscriptions.push(disposable);
}

// MIT Licensed code from: https://github.com/georgewfraser/vscode-javac
function findJavaExecutable(binname: string) {
    binname = correctBinname(binname);

    // First search each JAVA_HOME bin folder
    if (process.env['JAVA_HOME']) {
        let workspaces = process.env['JAVA_HOME'].split(path.delimiter);
        for (let i = 0; i < workspaces.length; i++) {
            let binpath = path.join(workspaces[i], 'bin', binname);
            if (fs.existsSync(binpath)) {
                return binpath;
            }
        }
    }

    // Then search PATH parts
    if (process.env['PATH']) {
        let pathparts = process.env['PATH'].split(path.delimiter);
        for (let i = 0; i < pathparts.length; i++) {
            let binpath = path.join(pathparts[i], binname);
            if (fs.existsSync(binpath)) {
                return binpath;
            }
        }
    }

    // Else return the binary name directly (this will likely always fail downstream) 
    return null;
}

function correctBinname(binname: string) {
    if (process.platform === 'win32')
        return binname + '.exe';
    else
        return binname;
}
...