Esempio n. 1
0
def download_global_model(ls: LanguageServer, *args):
    ui.set_language_server(ls)
    try:
        ui.download_global_model()
    except:
        ls.show_message_log(traceback.format_exc())
        raise
def client_server():
    c2s_r, c2s_w = os.pipe()
    s2c_r, s2c_w = os.pipe()

    def start(ls: LanguageServer, fdr, fdw):
        # TODO: better patch is needed
        # disable `close()` to avoid error messages
        close = ls.loop.close
        ls.loop.close = lambda: None
        ls.start_io(os.fdopen(fdr, "rb"), os.fdopen(fdw, "wb"))
        ls.loop.close = close

    server = CMakeLanguageServer(asyncio.new_event_loop())
    server_thread = Thread(target=start, args=(server, c2s_r, s2c_w))
    server_thread.start()

    client = LanguageServer(asyncio.new_event_loop())
    client_thread = Thread(target=start, args=(client, s2c_r, c2s_w))
    client_thread.start()

    yield client, server

    client.send_notification(features.EXIT)
    server.send_notification(features.EXIT)
    server_thread.join()
    client_thread.join()
 def start(ls: LanguageServer, fdr, fdw):
     # TODO: better patch is needed
     # disable `close()` to avoid error messages
     close = ls.loop.close
     ls.loop.close = lambda: None
     ls.start_io(os.fdopen(fdr, "rb"), os.fdopen(fdw, "wb"))
     ls.loop.close = close
Esempio n. 4
0
def did_change_configuration(
        ls: LanguageServer,
        params: types.DidChangeConfigurationParams) -> None:
    """Change the bibliography path on configuration change"""
    try:
        __update_bibliography_configuration([params.settings["citation"]])
    except FileNotFoundError as err:
        ls.show_message("File Not Found Error: {}".format(err),
                        msg_type=types.MessageType.Error)
Esempio n. 5
0
async def parseAndSendDiagnostics(
    ls: LanguageServer,
    uri: str,
) -> None:
    await asyncio.sleep(DEBOUNCE_DELAY)
    diagnostics = []
    async for diag in diagnostic.getDiagnostics(ls, uri):
        diagnostics.append(diag)
    ls.publish_diagnostics(uri, diagnostics)
Esempio n. 6
0
def client_server():
    """ A fixture to setup a LSP client/server """
    from cp2k_input_tools.ls import setup_ls
    from pygls.server import LanguageServer
    from pygls import features
    from pygls.types import LogMessageParams, PublishDiagnosticsParams

    # Client to Server pipe
    csr, csw = os.pipe()

    # Server to client pipe
    scr, scw = os.pipe()

    server = LanguageServer()
    setup_ls(server)

    server_thread = Thread(target=server.start_io,
                           args=(os.fdopen(csr, "rb"), os.fdopen(scw, "wb")))

    server_thread.daemon = True
    server_thread.start()

    # Add thread id to the server (just for testing)
    server.thread_id = server_thread.ident

    # Setup client
    client = LanguageServer(asyncio.new_event_loop())

    # make sure our minimal client can store log messages and diagnostics

    @client.feature(features.WINDOW_LOG_MESSAGE)
    async def client_log_message(ls, params: LogMessageParams):
        ls.msg_type = params.type
        ls.msg = params.message

    @client.feature(features.TEXT_DOCUMENT_PUBLISH_DIAGNOSTICS)
    async def client_handle_diagnostics(ls, params: PublishDiagnosticsParams):
        ls.diagnostics = params.diagnostics

    client_thread = Thread(target=client.start_io,
                           args=(os.fdopen(scr, "rb"), os.fdopen(csw, "wb")))

    client_thread.daemon = True
    client_thread.start()

    yield client, server

    shutdown_response = client.lsp.send_request(
        features.SHUTDOWN).result(timeout=CALL_TIMEOUT)

    assert shutdown_response is None
    client.lsp.notify(features.EXIT)
Esempio n. 7
0
def initialized(ls: LanguageServer, _params: types.InitializeParams) -> None:
    """Initialization handler; sets rootPath and gets configuration, if possible"""
    if has_get_configuration:
        try:
            ls.get_configuration(
                types.ConfigurationParams(item=types.ConfigurationItem(
                    scope_uri="",
                    section=CitationLanguageServer.CONFIGURATION_SECTION,
                )),
                __update_bibliography_configuration,
            )
        except FileNotFoundError as err:
            ls.show_message("File Not Found Error: {}".format(err),
                            types.MessageType.Error)
Esempio n. 8
0
    def setUp(self):
        self.folder = Path(__file__).parent / 'verilog'
        # Client to Server pipe
        csr, csw = os.pipe()
        # Server to client pipe
        scr, scw = os.pipe()

        # Server
        self.server = server
        # Client
        self.client = LanguageServer(asyncio.new_event_loop())

        server_thread = Thread(target=self.server.start_io,
                               args=(os.fdopen(csr,
                                               'rb'), os.fdopen(scw, 'wb')))
        server_thread.daemon = True
        server_thread.start()

        client_thread = Thread(target=self.client.start_io,
                               args=(os.fdopen(scr,
                                               'rb'), os.fdopen(csw, 'wb')))
        client_thread.daemon = True
        client_thread.start()
        # Initialize server
        self.server.lsp.bf_initialize(
            InitializeParams(process_id=1234,
                             root_uri=self.folder.as_uri(),
                             capabilities=None))
        print("Setup done!")
Esempio n. 9
0
async def test_tcp_connection_lost():
    loop = asyncio.new_event_loop()

    server = LanguageServer(loop=loop)

    server.lsp.connection_made = Mock()
    server.lsp.connection_lost = Mock()

    # Run the server over TCP in a separate thread
    server_thread = Thread(target=server.start_tcp, args=('127.0.0.1', 0, ))
    server_thread.daemon = True
    server_thread.start()

    # Wait for server to be ready
    while server._server is None:
        await asyncio.sleep(.5)

    # Simulate client's connection
    port = server._server.sockets[0].getsockname()[1]
    reader, writer = await asyncio.open_connection('127.0.0.1', port)
    await asyncio.sleep(1)

    assert server.lsp.connection_made.called

    # Socket is closed (client's process is terminated)
    writer.close()
    await asyncio.sleep(1)

    assert server.lsp.connection_lost.called
Esempio n. 10
0
def test_allow_custom_protocol_derived_from_lsp():
    class CustomProtocol(LanguageServerProtocol):
        pass

    server = LanguageServer(protocol_cls=CustomProtocol)

    assert isinstance(server.lsp, CustomProtocol)
Esempio n. 11
0
def _diagnose(english_server: LanguageServer, params):
    # Get document from workspace
    text_doc = english_server.workspace.get_document(params.textDocument.uri)
    raw_results = proselint.tools.lint(text_doc.source)
    diagnostics = []
    for _, message, line, col, _, _, length, _, _ in raw_results:
        diagnostics += [
            Diagnostic(
                range=Range(Position(line, col - 1),
                            Position(line, col + length)),
                message=message,
                severity=DiagnosticSeverity.Warning,
                source="eng-lsp",
            )
        ]

    # Send diagnostics
    english_server.publish_diagnostics(params.textDocument.uri, diagnostics)
Esempio n. 12
0
    def __init__(self):
        from pygls.lsp.methods import (
            TEXT_DOCUMENT_PUBLISH_DIAGNOSTICS,
            WINDOW_LOG_MESSAGE,
        )
        from pygls.lsp.types import LogMessageParams, PublishDiagnosticsParams
        from pygls.server import LanguageServer

        from cp2k_input_tools.ls import setup_cp2k_ls_server

        # Client to Server pipe
        csr, csw = os.pipe()
        # Server to client pipe
        scr, scw = os.pipe()

        # Setup Server
        self.server = LanguageServer()
        setup_cp2k_ls_server(self.server)
        self.server_thread = Thread(target=self.server.start_io,
                                    args=(os.fdopen(csr, "rb"),
                                          os.fdopen(scw, "wb")))
        self.server_thread.daemon = True

        # Setup client
        self.client = LanguageServer(asyncio.new_event_loop())

        # make sure our minimal client can store log messages and diagnostics
        self.client.msgs = []
        self.client.diagnostics = None

        @self.client.feature(WINDOW_LOG_MESSAGE)
        async def client_log_message(ls, params: LogMessageParams):
            ls.msgs.append(params)

        @self.client.feature(TEXT_DOCUMENT_PUBLISH_DIAGNOSTICS)
        async def client_handle_diagnostics(ls,
                                            params: PublishDiagnosticsParams):
            ls.diagnostics = params.diagnostics

        self.client_thread = Thread(target=self.client.start_io,
                                    args=(os.fdopen(scr, "rb"),
                                          os.fdopen(csw, "wb")))
        self.client_thread.daemon = True
Esempio n. 13
0
    def __init__(self):
        # Client to Server pipe
        csr, csw = os.pipe()
        # Server to client pipe
        scr, scw = os.pipe()

        # Setup Server
        self.server = LanguageServer()
        self.server_thread = Thread(target=self.server.start_io,
                                    args=(os.fdopen(csr, 'rb'),
                                          os.fdopen(scw, 'wb')))
        self.server_thread.daemon = True

        # Setup client
        self.client = LanguageServer(asyncio.new_event_loop())
        self.client_thread = Thread(target=self.client.start_io,
                                    args=(os.fdopen(scr, 'rb'),
                                          os.fdopen(csw, 'wb')))
        self.client_thread.daemon = True
Esempio n. 14
0
def _mypy_check(ls: LanguageServer, uri: str, script: Script,
                result: List[types.Diagnostic]):
    from mypy import api
    assert jediEnvironment is not None
    version_info = jediEnvironment.version_info
    if config['diagnostic_on_change']:
        args = ['--command', script._code]
    else:
        args = [to_fs_path(uri)]
    lines = api.run([
        '--python-executable', jediEnvironment.executable, '--python-version',
        f'{version_info.major}.{version_info.minor}', '--config-file',
        get_mypy_config(ls,
                        uri), '--hide-error-context', '--show-column-numbers',
        '--show-error-codes', '--no-pretty', '--no-error-summary'
    ] + args)
    if lines[1]:
        ls.show_message(lines[1], types.MessageType.Error)
        return

    for line in lines[0].split('\n'):
        parts = line.split(':', 4)
        if len(parts) < 5:
            continue
        _fn, row, column, err_type, message = parts
        row = int(row) - 1
        column = int(column) - 1
        if err_type.strip() == 'note':
            severity = types.DiagnosticSeverity.Hint
        else:
            severity = types.DiagnosticSeverity.Warning
        result.append(
            types.Diagnostic(range=types.Range(
                start=types.Position(line=row, character=column),
                end=types.Position(line=row,
                                   character=len(script._code_lines[row]))),
                             message=message.strip(),
                             severity=severity,
                             source='mypy'))
    return result
Esempio n. 15
0
def _validate(ls: LanguageServer, uri: str):
    # Jedi
    script = get_script(ls, uri)
    result = [
        types.Diagnostic(types.Range(
            types.Position(x.line - 1, x.column),
            types.Position(x.until_line - 1, x.until_column)),
                         'Invalid syntax',
                         types.DiagnosticSeverity.Error,
                         source='jedi') for x in script.get_syntax_errors()
    ]
    if result:
        ls.publish_diagnostics(uri, result)
        return

    # pyflakes
    pyflakes_check(script._code, script.path,
                   PyflakesReporter(result, script, config['pyflakes_errors']))

    # pycodestyle
    codestyleopts = get_pycodestyle_options(ls, uri)
    CodestyleChecker(script.path, script._code.splitlines(True), codestyleopts,
                     CodestyleReport(codestyleopts, result)).check_all()

    if config['mypy_enabled']:
        try:
            _mypy_check(ls, uri, script, result)
        except Exception as e:
            ls.show_message(f'mypy check error: {e}',
                            types.MessageType.Warning)

    ls.publish_diagnostics(uri, result)
Esempio n. 16
0
def client_server():
    """ A fixture to setup a client/server """

    # Client to Server pipe
    csr, csw = os.pipe()
    # Server to client pipe
    scr, scw = os.pipe()

    # Setup server
    server = LanguageServer()
    setup_ls_features(server)

    server_thread = Thread(target=server.start_io, args=(
        os.fdopen(csr, 'rb'), os.fdopen(scw, 'wb')
    ))

    server_thread.daemon = True
    server_thread.start()

    # Add thread id to the server (just for testing)
    server.thread_id = server_thread.ident

    # Setup client
    client = LanguageServer(asyncio.new_event_loop())

    client_thread = Thread(target=client.start_io, args=(
        os.fdopen(scr, 'rb'), os.fdopen(csw, 'wb')))

    client_thread.daemon = True
    client_thread.start()

    yield client, server

    shutdown_response = client.lsp.send_request(
        features.SHUTDOWN).result(timeout=CALL_TIMEOUT)
    assert shutdown_response is None
    client.lsp.notify(features.EXIT)
Esempio n. 17
0
def client_server():
    """ A fixture to setup a client/server """

    # Client to Server pipe
    csr, csw = os.pipe()
    # Server to client pipe
    scr, scw = os.pipe()

    # Run server
    server_thread = Thread(target=textx_server.start_io, args=(
        os.fdopen(csr, 'rb'), os.fdopen(scw, 'wb')
    ))
    server_thread.daemon = True
    server_thread.start()

    # Setup client
    client = LanguageServer(asyncio.new_event_loop())
    client_thread = Thread(target=client.start_io, args=(
        os.fdopen(scr, 'rb'), os.fdopen(csw, 'wb')
    ))
    client_thread.daemon = True
    client_thread.start()

    # Register client features to catch responses
    register_client_features(client)

    # Initialize server
    initialize_server(textx_server)

    yield client, textx_server

    shutdown_response = client.lsp.send_request(
        SHUTDOWN).result(timeout=CALL_TIMEOUT)

    assert shutdown_response is None
    client.send_notification(EXIT)
Esempio n. 18
0
async def test_io_connection_lost():
    # Client to Server pipe.
    csr, csw = os.pipe()
    # Server to client pipe.
    scr, scw = os.pipe()

    server = LanguageServer(loop=asyncio.new_event_loop())
    server.lsp.connection_made = Mock()
    server_thread = Thread(target=server.start_io,
                           args=(os.fdopen(csr, 'rb'), os.fdopen(scw, 'wb')))
    server_thread.daemon = True
    server_thread.start()

    # Wait for server to be ready
    while not server.lsp.connection_made.called:
        await asyncio.sleep(.5)

    # Pipe is closed (client's process is terminated)
    os.close(csw)
    server_thread.join()
Esempio n. 19
0
def client_server():
    """A fixture that sets up an LSP server + client.

    Originally based on https://github.com/openlawlibrary/pygls/blob/59f3056baa4de4c4fb374d3657194f2669c174bc/tests/conftest.py  # noqa: E501
    """

    # Pipes so that client + server can communicate
    csr, csw = os.pipe()
    scr, scw = os.pipe()

    # Server setup
    server = create_language_server(BUILTIN_MODULES)
    server_thread = threading.Thread(
        name="ServThread",
        target=server.start_io,
        args=(os.fdopen(csr, "rb"), os.fdopen(scw, "wb")),
    )

    server_thread.daemon = True
    server_thread.start()

    # Not entirely sure what this step does...
    server.thread_id = server_thread.ident

    # Client setup - we can get away with a vanilla 'LanguageServer' for this
    client = LanguageServer(asyncio.new_event_loop())
    client_thread = threading.Thread(
        name="ClntThread",
        target=client.start_io,
        args=(os.fdopen(scr, "rb"), os.fdopen(csw, "wb")),
    )

    client_thread.daemon = True
    client_thread.start()

    yield client, server

    response = client.lsp.send_request(SHUTDOWN).result(timeout=2)
    assert response is None
    client.lsp.notify(EXIT)
Esempio n. 20
0
def suggest_naming(ls: LanguageServer, *args):
    ui.set_language_server(ls)
    ls.show_message("Suggesting naming...")

    paths = []
    for d in ls.workspace.documents:
        p = Path(urllib.parse.unquote_plus(urllib.parse.urlparse(d).path))
        if p.suffix != ".v":
            continue
        paths.append(p)

    if len(paths) == 0:
        ls.show_message("Please open at least one .v file!", MessageType.Error)

    for p in paths:
        try:
            ui.suggest_naming(p)
        except:
            ls.show_message_log(traceback.format_exc())
            raise
Esempio n. 21
0
 def did_close(server: LanguageServer, params: DidCloseTextDocumentParams):
     """Text document did close notification."""
     server.show_message("Text Document Did Close")
Esempio n. 22
0
            diagnostics += [
                Diagnostic(erange,
                           msg,
                           source=type(cp2k_inp_server).__name__,
                           related_information=[])
            ]

    ls.publish_diagnostics(text_doc.uri, diagnostics)


def setup_ls(server):
    @server.feature(TEXT_DOCUMENT_DID_CHANGE)
    def did_change(ls, params: DidChangeTextDocumentParams):
        """Text document did change notification."""
        _validate(ls, params)

    @server.feature(TEXT_DOCUMENT_DID_CLOSE)
    def did_close(server: LanguageServer, params: DidCloseTextDocumentParams):
        """Text document did close notification."""
        server.show_message("Text Document Did Close")

    @server.feature(TEXT_DOCUMENT_DID_OPEN)
    async def did_open(ls, params: DidOpenTextDocumentParams):
        """Text document did open notification."""
        ls.show_message("Text Document Did Open")
        _validate(ls, params)


cp2k_inp_server = LanguageServer()
setup_ls(cp2k_inp_server)
Esempio n. 23
0
from pygls.features import TEXT_DOCUMENT_DID_OPEN, TEXT_DOCUMENT_DID_SAVE, TEXT_DOCUMENT_DID_CHANGE
from pygls import features
from pygls.server import LanguageServer
from pygls.types import Range, Position, Diagnostic, SignatureHelp, SignatureInformation, Hover

from checker import check
import logging

server = LanguageServer()
logging.basicConfig(level=logging.DEBUG)


class Checker:
    def validate(self, source):
        self.itpr = check(source)
        diagnostics = []
        logging.debug(f'itpr errors: {self.itpr.errors}')
        for item in self.itpr.errors:
            l1 = item['lineno'] - 1
            c1 = item['col_offset']
            l2 = item['end_lineno'] - 1
            c2 = item['end_col_offset']
            msg = item['error'].message
            diagnostics.append(
                Diagnostic(range=Range(Position(l1, c1), Position(l2, c2)),
                           message=msg,
                           source="PDChecker"))
        return diagnostics

    def help(self, pos):
        def inside(node):
Esempio n. 24
0
        ):
            server.feature(DOCUMENT_SYMBOL)(document_symbol)
        else:
            server.feature(DOCUMENT_SYMBOL)(document_symbol_legacy)
        init = rgetattr(params, "initializationOptions")
        if rgetattr(init, "diagnostics.enable", True):
            if rgetattr(init, "diagnostics.didOpen", True):
                SERVER.feature(TEXT_DOCUMENT_DID_OPEN)(did_open)
            if rgetattr(init, "diagnostics.didChange", True):
                SERVER.feature(TEXT_DOCUMENT_DID_CHANGE)(did_change)
            if rgetattr(init, "diagnostics.didSave", True):
                SERVER.feature(TEXT_DOCUMENT_DID_SAVE)(did_save)
        return super().bf_initialize(params)


SERVER = LanguageServer(protocol_cls=JediLanguageServerProtocol)

# Static capabilities, no configuration


@SERVER.feature(COMPLETION, trigger_characters=[".", "'", '"'])
def completion(server: LanguageServer,
               params: CompletionParams) -> CompletionList:
    """Returns completion items"""
    jedi_script = jedi_utils.script(server.workspace, params.textDocument.uri)
    jedi_lines = jedi_utils.line_column(params.position)
    completions = jedi_script.complete(**jedi_lines)
    char = pygls_utils.char_before_cursor(
        document=server.workspace.get_document(params.textDocument.uri),
        position=params.position,
    )
Esempio n. 25
0
def test_forbid_custom_protocol_not_derived_from_lsp():
    class CustomProtocol:
        pass

    with pytest.raises(TypeError):
        LanguageServer(protocol_cls=CustomProtocol)
Esempio n. 26
0
def _publish_diagnostics(server: LanguageServer, uri: str):
    """Helper function to publish diagnostics for a file"""
    jedi_script = jedi_utils.script(server.workspace, uri)
    errors = jedi_script.get_syntax_errors()
    diagnostics = [jedi_utils.lsp_diagnostic(error) for error in errors]
    server.publish_diagnostics(uri, diagnostics)
Esempio n. 27
0
    def __init__(
        self, method: ConnectionMethod, host: Optional[str], port: Optional[int]
    ) -> None:
        self._method = method
        self._host = host
        self._port = port

        if self._method == ConnectionMethod.TCP:
            if host is None or port is None:
                raise ValueError("host and port is required when method is TCP")

        self._server = LanguageServer()
        self._config = LanguageServerConfiguration.default()
        self._workspace = Workspace(self._server)

        self._register_command(
            Commands.ReloadServerConfiguration,
            self._on_reload_server_config,
        )
        self._register_command(
            Commands.LintDocument,
            self._on_lint_document,
        )
        self._register_command(
            Commands.FormatDocument,
            self._on_format_document,
        )
        self._register_command(
            Commands.LintWorkspace,
            self._on_lint_workspace,
        )
        self._register_command(
            Commands.FormatWorkspace,
            self._on_format_workspace,
        )

        self._register_feature("$/setTrace", None, lambda *args, **kwargs: None)
        self._register_feature(
            lsp.methods.INITIALIZE,
            None,
            self._on_initialize,
        )
        self._register_feature(
            lsp.methods.WORKSPACE_DID_CHANGE_CONFIGURATION,
            None,
            self._on_workspace_did_change_configuration,
        )
        self._register_feature(
            lsp.methods.FORMATTING,
            lsp.types.DocumentFormattingOptions(),
            self._on_formatting,
        )
        self._register_feature(
            lsp.methods.TEXT_DOCUMENT_DID_SAVE,
            None,
            self._on_text_document_did_save,
        )
        self._register_feature(
            lsp.methods.TEXT_DOCUMENT_DID_OPEN,
            None,
            self._on_text_document_did_open,
        )
        self._register_feature(
            lsp.methods.TEXT_DOCUMENT_DID_CLOSE,
            None,
            self._on_text_document_did_close,
        )
        self._register_feature(
            lsp.methods.TEXT_DOCUMENT_DID_CHANGE,
            None,
            self._on_text_document_did_change,
        )
        self._register_feature(
            lsp.methods.CODE_ACTION,
            lsp.types.CodeActionOptions(
                code_action_kinds=[lsp.types.CodeActionKind.QuickFix]
            ),
            self._provide_code_action,
        )
Esempio n. 28
0
class Server:
    def __init__(
        self, method: ConnectionMethod, host: Optional[str], port: Optional[int]
    ) -> None:
        self._method = method
        self._host = host
        self._port = port

        if self._method == ConnectionMethod.TCP:
            if host is None or port is None:
                raise ValueError("host and port is required when method is TCP")

        self._server = LanguageServer()
        self._config = LanguageServerConfiguration.default()
        self._workspace = Workspace(self._server)

        self._register_command(
            Commands.ReloadServerConfiguration,
            self._on_reload_server_config,
        )
        self._register_command(
            Commands.LintDocument,
            self._on_lint_document,
        )
        self._register_command(
            Commands.FormatDocument,
            self._on_format_document,
        )
        self._register_command(
            Commands.LintWorkspace,
            self._on_lint_workspace,
        )
        self._register_command(
            Commands.FormatWorkspace,
            self._on_format_workspace,
        )

        self._register_feature("$/setTrace", None, lambda *args, **kwargs: None)
        self._register_feature(
            lsp.methods.INITIALIZE,
            None,
            self._on_initialize,
        )
        self._register_feature(
            lsp.methods.WORKSPACE_DID_CHANGE_CONFIGURATION,
            None,
            self._on_workspace_did_change_configuration,
        )
        self._register_feature(
            lsp.methods.FORMATTING,
            lsp.types.DocumentFormattingOptions(),
            self._on_formatting,
        )
        self._register_feature(
            lsp.methods.TEXT_DOCUMENT_DID_SAVE,
            None,
            self._on_text_document_did_save,
        )
        self._register_feature(
            lsp.methods.TEXT_DOCUMENT_DID_OPEN,
            None,
            self._on_text_document_did_open,
        )
        self._register_feature(
            lsp.methods.TEXT_DOCUMENT_DID_CLOSE,
            None,
            self._on_text_document_did_close,
        )
        self._register_feature(
            lsp.methods.TEXT_DOCUMENT_DID_CHANGE,
            None,
            self._on_text_document_did_change,
        )
        self._register_feature(
            lsp.methods.CODE_ACTION,
            lsp.types.CodeActionOptions(
                code_action_kinds=[lsp.types.CodeActionKind.QuickFix]
            ),
            self._provide_code_action,
        )

    def _register_command(self, command_name: str, handler: Callable[..., Any]) -> None:
        @self._server.command(command_name)
        def cb(*args: Any, **kwargs: Any) -> Any:
            return handler(*args, **kwargs)

    def _register_feature(
        self, feature_name: str, option: Any, handler: Callable[..., Any]
    ) -> None:
        # NOTE: pygls calls setattr in `feature` decorator to add their own field.
        # Since a method doesn't allow setattr for undefined fields,
        # we cannot use it for the decorator.
        # Thus We define temporary function instead.
        @self._server.feature(feature_name, option)
        def cb(*args: Any, **kwargs: Any) -> Any:
            return handler(*args, **kwargs)

    def _on_config_received(self, data: Any) -> None:
        try:
            self._config = LanguageServerConfiguration.parse_obj(data[0])
        except ValidationError as e:
            self._server.show_message_log(f"Error occurred: {e}")
        except Exception as e:
            self._server.show_message_log(f"Error occurred: {e}")

    def _request_config(self) -> None:
        self._server.get_configuration(
            lsp.types.ConfigurationParams(
                items=[
                    lsp.types.ConfigurationItem(
                        scope_uri="", section=CONFIGURATION_SECTION_NAME
                    )
                ]
            ),
            self._on_config_received,
        )

    def _on_initialize(self, params: lsp.types.InitializeParams) -> None:
        # NOTE: The return value from this method will be ignored.
        # pygls.LanguageServerProtocol provides some predefined lsp features.
        # It calls methods starting with `bf_`, then call use defined methods.
        # User defined methods are wrapped by the decorator in pygls,
        # and it doesn't use the return values from the methods.
        # See: https://github.com/openlawlibrary/pygls/blob/b5dcfa36ee3fab2cd0f3bf29248d58f5ad3b6796/pygls/protocol.py#L62-L75  # NOQA
        options = params.initialization_options
        if options is not None:
            config = options.get("config", None)
            if config is not None:
                self._on_config_received([config])

    def _on_workspace_did_change_configuration(
        self, params: lsp.types.DidChangeConfigurationParams
    ) -> None:
        settings = params.settings
        if settings is not None and isinstance(settings, dict):
            config = settings.get("config", None)
            if config is not None:
                self._on_config_received([config])

    def _publish_file_diagnostics(
        self,
        targets: Sequence[str],
        runtime: FileRuntime,
    ) -> None:
        for target in targets:
            runtime.update_diagnostics(target, None)

        diagnostics = runtime.get_diagnostics()
        self._server.publish_diagnostics(
            runtime.uri,
            diagnostics,
        )

    def _publish_workspace_diagnostics(
        self,
        targets: Sequence[str],
        runtime: WorkspaceRuntime,
    ) -> None:
        for target in targets:
            runtime.update_diagnostics(target)

        to_publish: DefaultDict[str, List[Diagnostic]] = collections.defaultdict(list)
        data = list(runtime.iter_diagnostics())

        for d in data:
            to_publish[d.uri].append(d.diagnostic)

        for uri, diagnostics in to_publish.items():
            self._server.publish_diagnostics(
                uri,
                diagnostics,
            )

    def _on_reload_server_config(self, *args: Any) -> None:
        self._request_config()

    def _handle_document_command(self, request: Any, targets: Sequence[str]) -> None:
        uri = _get_request_params(request)
        if uri is None:
            return

        runtime = self._workspace.create_file_runtime(uri, force=True)
        if runtime is None:
            return

        self._publish_file_diagnostics(targets, runtime)

    def _on_formatting(self, params: lsp.types.DocumentFormattingParams) -> None:
        # TODO: Consider adding unregistration config of this capability
        # for someone who wants opt-out this feature.
        uri = params.text_document.uri
        self._handle_document_command([uri], self._config.format_targets)

    def _on_lint_document(self, args: Any) -> None:
        self._handle_document_command(args, self._config.lint_targets)

    def _on_format_document(self, args: Any) -> None:
        self._handle_document_command(args, self._config.format_targets)

    def _handle_workspace_command(self, request: Any, targets: Sequence[str]) -> None:
        root_uri = self._server.workspace.root_uri
        root_path = self._server.workspace.root_path
        if root_uri is None or root_path is None:
            self._server.show_message(
                "workspace is not opened", lsp.types.MessageType.Error
            )
            return

        runtime = self._workspace.get_workspace_runtime(
            root_uri, pathlib.Path(root_path)
        )
        if runtime is None:
            return

        self._publish_workspace_diagnostics(targets, runtime)

    def _on_lint_workspace(self, args: Any) -> None:
        self._handle_workspace_command(args, self._config.lint_targets)

    def _on_format_workspace(self, args: Any) -> None:
        self._handle_workspace_command(args, self._config.format_targets)

    def _on_text_document_did_open(
        self, params: lsp.types.DidOpenTextDocumentParams
    ) -> None:
        uri = params.text_document.uri
        runtime = self._workspace.create_file_runtime(uri)
        if runtime is None:
            return

        self._publish_file_diagnostics(self._config.lint_targets, runtime)

    def _on_text_document_did_close(
        self, params: lsp.types.DidCloseTextDocumentParams
    ) -> None:
        pass

    def _on_text_document_did_save(
        self, params: lsp.types.DidSaveTextDocumentParams
    ) -> None:
        if not self._config.enable_lint_on_save:
            return None

        runtime = self._workspace.get_file_runtime(params.text_document.uri)
        if runtime is None:
            return

        self._publish_file_diagnostics(self._config.lint_targets, runtime)

    def _on_text_document_did_change(
        self,
        params: lsp.types.DidChangeTextDocumentParams,
    ) -> None:
        runtime = self._workspace.get_file_runtime(params.text_document.uri)
        if runtime is None:
            return

        changes = params.content_changes
        for change in changes:
            if not isinstance(change, lsp.types.TextDocumentContentChangeEvent):
                continue
            change_range = change.range

            if change_range is None:
                continue

            runtime.update_diagnostics_range(change_range, change.text)

    def _provide_code_action(
        self, params: lsp.types.CodeActionParams
    ) -> Optional[Sequence[Union[lsp.types.Command, lsp.types.CodeAction]]]:
        if not self._config.enable_code_action:
            return None

        runtime = self._workspace.get_file_runtime(params.text_document.uri)
        if runtime is None:
            return []

        return runtime.query_code_actions(params.range)

    def start(self) -> None:
        _logger.info("starting server")
        if self._method == ConnectionMethod.IO:
            _logger.info("use stdio for the communication")
            self._server.start_io()
        else:
            assert self._method == ConnectionMethod.TCP, self._method
            _logger.info("use tcp for the communication")
            assert self._host is not None
            assert self._port is not None
            self._server.start_tcp(self._host, self._port)
Esempio n. 29
0
                            WORKSPACE_EXECUTE_COMMAND)
from pygls.server import LanguageServer
from pygls.types import (CompletionItem, CompletionItemKind, CompletionList,
                         CompletionParams, Diagnostic, DiagnosticSeverity,
                         DidChangeTextDocumentParams,
                         DidOpenTextDocumentParams, DidSaveTextDocumentParams,
                         Hover, InsertTextFormat, Location, MarkupContent,
                         MarkupKind, TextDocumentContentChangeEvent,
                         TextDocumentPositionParams)
import threading
import time

# TODO remove this for production
logging.basicConfig(filename='bio-idek.log', filemode='w', level=logging.DEBUG)
'''=====Server-related Code===='''
server = LanguageServer()
services = WebServices()


def to_diagnostic(issue: Issue):
    '''Convert the Stibium Issue object to a pygls Diagnostic object'''
    severity = DiagnosticSeverity.Error
    if issue.severity == IssueSeverity.Warning:
        severity = DiagnosticSeverity.Warning

    return Diagnostic(range=pygls_range(issue.range),
                      message=issue.message,
                      severity=severity)


def _publish_diagnostics(uri: str) -> AntFile:
Esempio n. 30
0
    CompletionItemKind,
    CompletionOptions,
    CompletionParams,
    DidChangeTextDocumentParams,
    DidChangeWatchedFilesParams,
    DidOpenTextDocumentParams,
    MarkupContent,
    MarkupKind,
    Position,
    Range,
    TextEdit,
)

from . import buildout, diagnostic

server = LanguageServer()
logger = logging.getLogger(__name__)

DEBOUNCE_DELAY = 0.3


async def parseAndSendDiagnostics(
    ls: LanguageServer,
    uri: str,
) -> None:
    await asyncio.sleep(DEBOUNCE_DELAY)
    diagnostics = []
    async for diag in diagnostic.getDiagnostics(ls, uri):
        diagnostics.append(diag)
    ls.publish_diagnostics(uri, diagnostics)