how to build language server protocol in VSCode by using Java code in server side?

时间:2018-12-03 13:16:20

标签: java visual-studio-code vscode-extensions language-server-protocol

Description: I'm trying to build an extension for VSCode using client-server side protocol. In server side, i put .jar file which includes Java code. It defines structure of function in BNF and parse it. After that it returns errors of function syntax which is given to system interms of symbols,charposition etc.

Inside of server, .jar file is covered. So, the purpose is to access this file and provide a connection with client side.

Also , another thing is the error when i debug the code below;

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)

when i tried to figure it out what's happening inside, many stuff is telling that it can be depending on version of Vscode or libraries i used. But i could not fix it.

If someone knows whats the point that i am missing here, i will appreciate that.

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;
}

0 个答案:

没有答案