Repository: microsoft/multilspy
Pull request #68: Feat/dart
Author: login: v4rgas
Created: 2025-02-28T01:12:48Z | Merged: 2025-03-03T03:34:09Z



Diff:
diff --git a/.gitignore b/.gitignore
index a7115ea3..8464aab8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -402,6 +402,7 @@ src/multilspy/language_servers/gopls/static/
 src/multilspy/language_servers/omnisharp/static/
 src/multilspy/language_servers/rust_analyzer/static/
 src/multilspy/language_servers/typescript_language_server/static/
+src/multilspy/language_servers/dart_language_server/static/
 
 # Virtual Environment
 .venv/
diff --git a/README.md b/README.md
index 90a4e588..5e70e98c 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 ## Introduction
 This repository hosts `multilspy`, a library developed as part of research conducted for NeruIPS 2023 paper titled ["Monitor-Guided Decoding of Code LMs with Static Analysis of Repository Context"](https://neurips.cc/virtual/2023/poster/70362) (["Guiding Language Models of Code with Global Context using Monitors"](https://arxiv.org/abs/2306.10763) on Arxiv). The paper introduces Monitor-Guided Decoding (MGD) for code generation using Language Models, where a monitor uses static analysis to guide the decoding, ensuring that the generated code follows various correctness properties, like absence of hallucinated symbol names, valid order of method calls, etc. For further details about Monitor-Guided Decoding, please refer to the paper and GitHub repository [microsoft/monitors4codegen](https://github.com/microsoft/monitors4codegen).
 
-`multilspy` is a cross-platform library designed to simplify the process of creating language server clients to query and obtain results of various static analyses from a wide variety of language servers that communicate over the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/). It is easily extensible to support any [language that has a Language Server](https://microsoft.github.io/language-server-protocol/implementors/servers/) and currently supports Java, Rust, C#, Go, JavaScript and Python. We aim to continuously add support for more language servers and languages.
+`multilspy` is a cross-platform library designed to simplify the process of creating language server clients to query and obtain results of various static analyses from a wide variety of language servers that communicate over the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/). It is easily extensible to support any [language that has a Language Server](https://microsoft.github.io/language-server-protocol/implementors/servers/) and we aim to continuously add support for more language servers and languages.
 
 [Language servers]((https://microsoft.github.io/language-server-protocol/overviews/lsp/overview/)) are tools that perform a variety of static analyses on code repositories and provide useful information such as type-directed code completion suggestions, symbol definition locations, symbol references, etc., over the [Language Server Protocol (LSP)](https://microsoft.github.io/language-server-protocol/overviews/lsp/overview/). Since LSP is language-agnostic, `multilspy` can provide the results for static analyses of code in different languages over a common interface.
 
@@ -35,6 +35,21 @@ To install `multilspy` using pip, execute the following command:
 pip install multilspy
 ```
 
+## Supported Languages
+`multilspy` currently supports the following languages:
+| Code Language | Language Server |
+| --- | --- | 
+| java | Eclipse JDTLS |
+| python | jedi-language-server |
+| rust | Rust Analyzer |
+| csharp | OmniSharp / RazorSharp |
+| typescript | TypeScriptLanguageServer |
+| javascript | TypeScriptLanguageServer |
+| go | gopls |
+| dart | Dart |
+| ruby | Solargraph |
+
+
 ## Usage
 Example usage:
 ```python
@@ -42,7 +57,7 @@ from multilspy import SyncLanguageServer
 from multilspy.multilspy_config import MultilspyConfig
 from multilspy.multilspy_logger import MultilspyLogger
 ...
-config = MultilspyConfig.from_dict({"code_language": "java"}) # Also supports "python", "rust", "csharp", "typescript", "javascript", "go"
+config = MultilspyConfig.from_dict({"code_language": "java"}) # Also supports "python", "rust", "csharp", "typescript", "javascript", "go", "dart", "ruby"
 logger = MultilspyLogger()
 lsp = SyncLanguageServer.create(config, logger, "/abs/path/to/project/root/")
 with lsp.start_server():
diff --git a/pyproject.toml b/pyproject.toml
index 0c66b929..6c1a8008 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,7 +9,7 @@ version = "0.0.13"
 authors = [
   { name="Lakshya A Agrawal", email="lakshya.aagrawal@gmail.com" },
 ]
-description = "A language-agnostic LSP client in Python, with a library interface. Intended to be used to build applications around language servers. Currently multilspy supports language servers for Python, Rust, Java, Go, JavaScript, Ruby and C#. Originally appeared as part of Monitor-Guided Decoding (https://github.com/microsoft/monitors4codegen)"
+description = "A language-agnostic LSP client in Python, with a library interface. Intended to be used to build applications around language servers. Currently multilspy supports language servers for Python, Rust, Java, Go, JavaScript, Ruby, C# and Dart. Originally appeared as part of Monitor-Guided Decoding (https://github.com/microsoft/monitors4codegen)"
 readme = "README.md"
 requires-python = ">=3.8, <4.0"
 classifiers = [
@@ -22,7 +22,10 @@ classifiers = [
     "Programming Language :: Java",
     "Programming Language :: Python",
     "Programming Language :: Rust",
-    "Programming Language :: JavaScript"
+    "Programming Language :: JavaScript",
+    "Programming Language :: Go",
+    "Programming Language :: Ruby",
+    "Programming Language :: Dart",
 ]
 
 dependencies = [
diff --git a/src/multilspy/language_server.py b/src/multilspy/language_server.py
index 665d39c4..1f72e24c 100644
--- a/src/multilspy/language_server.py
+++ b/src/multilspy/language_server.py
@@ -108,6 +108,10 @@ def create(cls, config: MultilspyConfig, logger: MultilspyLogger, repository_roo
             from multilspy.language_servers.solargraph.solargraph import Solargraph
 
             return Solargraph(config, logger, repository_root_path)
+        elif config.code_language == Language.DART:
+            from multilspy.language_servers.dart_language_server.dart_language_server import DartLanguageServer
+
+            return DartLanguageServer(config, logger, repository_root_path)
         else:
             logger.log(f"Language {config.code_language} is not supported", logging.ERROR)
             raise MultilspyException(f"Language {config.code_language} is not supported")
diff --git a/src/multilspy/language_servers/dart_language_server/dart_language_server.py b/src/multilspy/language_servers/dart_language_server/dart_language_server.py
new file mode 100644
index 00000000..b8143064
--- /dev/null
+++ b/src/multilspy/language_servers/dart_language_server/dart_language_server.py
@@ -0,0 +1,146 @@
+from contextlib import asynccontextmanager
+import logging
+import os
+import pathlib
+import shutil
+import stat
+from typing import AsyncIterator
+from multilspy.language_server import LanguageServer
+from multilspy.lsp_protocol_handler.server import ProcessLaunchInfo
+import json
+from multilspy.multilspy_utils import FileUtils, PlatformUtils
+
+
+class DartLanguageServer(LanguageServer):
+    """
+    Provides Dart specific instantiation of the LanguageServer class. Contains various configurations and settings specific to Dart.
+    """
+
+    def __init__(self, config, logger, repository_root_path):
+        """
+        Creates a DartServer instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
+        """
+
+        executable_path = self.setup_runtime_dependencies(logger)
+        super().__init__(
+            config,
+            logger,
+            repository_root_path,
+            ProcessLaunchInfo(cmd=executable_path, cwd=repository_root_path),
+            "dart",
+        )
+
+    def setup_runtime_dependencies(self, logger: "MultilspyLogger") -> str:
+        platform_id = PlatformUtils.get_platform_id()
+
+        with open(os.path.join(os.path.dirname(__file__), "runtime_dependencies.json"), "r") as f:
+            d = json.load(f)
+            del d["_description"]
+
+        runtime_dependencies = d["runtimeDependencies"]
+        runtime_dependencies = [
+            dependency for dependency in runtime_dependencies if dependency["platformId"] == platform_id.value
+        ]
+
+        assert len(runtime_dependencies) == 1
+        dependency = runtime_dependencies[0]
+
+        dart_ls_dir = os.path.join(os.path.dirname(__file__), "static", "dart-language-server")
+        dart_executable_path = os.path.join(dart_ls_dir, dependency["binaryName"])
+
+        if not os.path.exists(dart_ls_dir):
+            os.makedirs(dart_ls_dir)
+            FileUtils.download_and_extract_archive(
+                logger, dependency["url"], dart_ls_dir, dependency["archiveType"]
+            )
+
+
+        assert os.path.exists(dart_executable_path)
+        os.chmod(dart_executable_path, stat.S_IEXEC)
+
+        return f"{dart_executable_path} language-server --client-id multilspy.dart --client-version 1.2"
+
+
+    def _get_initialize_params(self, repository_absolute_path: str):
+        """
+        Returns the initialize params for the Dart Language Server.
+        """
+        with open(
+            os.path.join(os.path.dirname(__file__), "initialize_params.json"), "r"
+        ) as f:
+            d = json.load(f)
+
+        del d["_description"]
+
+        d["processId"] = os.getpid()
+        assert d["rootPath"] == "$rootPath"
+        d["rootPath"] = repository_absolute_path
+
+        assert d["rootUri"] == "$rootUri"
+        d["rootUri"] = pathlib.Path(repository_absolute_path).as_uri()
+
+        assert d["workspaceFolders"][0]["uri"] == "$uri"
+        d["workspaceFolders"][0]["uri"] = pathlib.Path(
+            repository_absolute_path
+        ).as_uri()
+
+        assert d["workspaceFolders"][0]["name"] == "$name"
+        d["workspaceFolders"][0]["name"] = os.path.basename(repository_absolute_path)
+
+        return d
+
+    @asynccontextmanager
+    async def start_server(self) -> AsyncIterator["DartLanguageServer"]:
+        """
+        Start the language server and yield when the server is ready.
+        """
+
+        async def execute_client_command_handler(params):
+            return []
+
+        async def do_nothing(params):
+            return
+
+        async def check_experimental_status(params):
+            pass
+
+        async def window_log_message(msg):
+            self.logger.log(f"LSP: window/logMessage: {msg}", logging.INFO)
+
+        self.server.on_request("client/registerCapability", do_nothing)
+        self.server.on_notification("language/status", do_nothing)
+        self.server.on_notification("window/logMessage", window_log_message)
+        self.server.on_request(
+            "workspace/executeClientCommand", execute_client_command_handler
+        )
+        self.server.on_notification("$/progress", do_nothing)
+        self.server.on_notification("textDocument/publishDiagnostics", do_nothing)
+        self.server.on_notification("language/actionableNotification", do_nothing)
+        self.server.on_notification(
+            "experimental/serverStatus", check_experimental_status
+        )
+
+        async with super().start_server():
+            self.logger.log(
+                "Starting dart-language-server server process", logging.INFO
+            )
+            await self.server.start()
+            initialize_params = self._get_initialize_params(self.repository_root_path)
+            self.logger.log(
+                "Sending initialize request to dart-language-server",
+                logging.DEBUG,
+            )
+            init_response = await self.server.send_request(
+                "initialize", initialize_params
+            )
+            self.logger.log(
+                f"Received initialize response from dart-language-server: {init_response}",
+                logging.INFO,
+            )
+
+            self.server.notify.initialized({})
+
+            yield self
+
+            await self.server.shutdown()
+            await self.server.stop()
diff --git a/src/multilspy/language_servers/dart_language_server/initialize_params.json b/src/multilspy/language_servers/dart_language_server/initialize_params.json
new file mode 100644
index 00000000..e90e408a
--- /dev/null
+++ b/src/multilspy/language_servers/dart_language_server/initialize_params.json
@@ -0,0 +1,23 @@
+{
+    "_description": "This file contains the initialization parameters for the Dart Language Server.",
+    "processId": "$processId",
+    "rootPath": "$rootPath",
+    "rootUri": "$rootUri",
+    "capabilities": {},
+    "initializationOptions": {
+        "onlyAnalyzeProjectsWithOpenFiles": false,
+        "suggestFromUnimportedLibraries": true,
+        "closingLabels": false,
+        "outline": false,
+        "flutterOutline": false,
+        "allowOpenUri": false
+    },
+    "trace": "verbose",
+    "workspaceFolders": [
+        {
+            "uri": "$uri",
+            "name": "$name"
+        }
+    ]
+    
+}
\ No newline at end of file
diff --git a/src/multilspy/language_servers/dart_language_server/runtime_dependencies.json b/src/multilspy/language_servers/dart_language_server/runtime_dependencies.json
new file mode 100644
index 00000000..8010b940
--- /dev/null
+++ b/src/multilspy/language_servers/dart_language_server/runtime_dependencies.json
@@ -0,0 +1,13 @@
+{
+    "_description": "Used to download the runtime dependencies for running Dart Language Server, downloaded from https://dart.dev/get-dart/archive",
+    "runtimeDependencies": [
+        {
+            "id": "DartLanguageServer",
+            "description": "Dart Language Server for Linux (x64)",
+            "url": "https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-linux-x64-release.zip",
+            "platformId": "linux-x64",
+            "archiveType": "zip",
+            "binaryName": "dart-sdk/bin/dart"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/multilspy/multilspy_config.py b/src/multilspy/multilspy_config.py
index 3628e9c4..f4014d02 100644
--- a/src/multilspy/multilspy_config.py
+++ b/src/multilspy/multilspy_config.py
@@ -18,6 +18,7 @@ class Language(str, Enum):
     JAVASCRIPT = "javascript"
     GO = "go"
     RUBY = "ruby"
+    DART = "dart"
 
     def __str__(self) -> str:
         return self.value
diff --git a/tests/multilspy/test_multilspy_dart.py b/tests/multilspy/test_multilspy_dart.py
new file mode 100644
index 00000000..6002cdea
--- /dev/null
+++ b/tests/multilspy/test_multilspy_dart.py
@@ -0,0 +1,76 @@
+"""
+This file contains tests for running the Dart Language Server.
+"""
+
+import pytest
+from multilspy import LanguageServer
+from multilspy.multilspy_config import Language
+from tests.test_utils import create_test_context
+from pathlib import PurePath
+
+pytest_plugins = ("pytest_asyncio",)
+
+
+@pytest.mark.asyncio
+async def test_multilspy_dart_open_nutri_tracker():
+    """
+    Test the working of multilspy with a Dart repository.
+    """
+    code_language = Language.DART
+    params = {
+        "code_language": code_language,
+        "repo_url": "https://github.com/simonoppowa/OpenNutriTracker/",
+        "repo_commit": "2df39185bdd822dec6a0e521f4c14e3eab6b0805",
+    }
+    with create_test_context(params) as context:
+        lsp = LanguageServer.create(
+            context.config, context.logger, context.source_directory
+        )
+
+        async with lsp.start_server():
+            result = await lsp.request_document_symbols(
+                str(
+                    PurePath("lib/core/presentation/widgets/copy_or_delete_dialog.dart")
+                )
+            )
+
+            assert isinstance(result, tuple)
+            assert len(result) == 2
+
+            symbols = result[0]
+            for symbol in symbols:
+                del symbol["deprecated"]
+                del symbol["kind"]
+                del symbol["location"]["uri"]
+
+            assert symbols == [
+                {
+                    "location": {
+                        "range": {
+                            "end": {"character": 24, "line": 3},
+                            "start": {"character": 6, "line": 3},
+                        },
+                    },
+                    "name": "CopyOrDeleteDialog",
+                },
+                {
+                    "containerName": "CopyOrDeleteDialog",
+                    "location": {
+                        "range": {
+                            "end": {"character": 26, "line": 4},
+                            "start": {"character": 8, "line": 4},
+                        },
+                    },
+                    "name": "CopyOrDeleteDialog",
+                },
+                {
+                    "containerName": "CopyOrDeleteDialog",
+                    "location": {
+                        "range": {
+                            "end": {"character": 14, "line": 7},
+                            "start": {"character": 9, "line": 7},
+                        },
+                    },
+                    "name": "build",
+                },
+            ]
diff --git a/tests/multilspy/test_sync_multilspy_dart.py b/tests/multilspy/test_sync_multilspy_dart.py
new file mode 100644
index 00000000..6072cb5d
--- /dev/null
+++ b/tests/multilspy/test_sync_multilspy_dart.py
@@ -0,0 +1,63 @@
+"""
+This file contains tests for running the Python Language Server: jedi-language-server
+"""
+
+from multilspy import SyncLanguageServer
+from multilspy.multilspy_config import Language
+from tests.test_utils import create_test_context
+from pathlib import PurePath
+
+
+def test_sync_multilspy_dart_open_nutri_tracker() -> None:
+    """
+    Test the working of multilspy with the Dart Language Server
+    """
+    code_language = Language.DART
+    params = {
+        "code_language": code_language,
+        "repo_url": "https://github.com/simonoppowa/OpenNutriTracker/",
+        "repo_commit": "2df39185bdd822dec6a0e521f4c14e3eab6b0805",
+    }
+    with create_test_context(params) as context:
+        lsp = SyncLanguageServer.create(
+            context.config, context.logger, context.source_directory
+        )
+
+        # All the communication with the language server must be performed inside the context manager
+        # The server process is started when the context manager is entered and is terminated when the context manager is exited.
+        with lsp.start_server():
+            result = lsp.request_references(
+                file_path=str(
+                    PurePath("lib/features/add_meal/presentation/add_meal_screen.dart")
+                ),
+                line=19,
+                column=5,
+            )
+
+            for item in result:
+                del item["uri"]
+                del item["absolutePath"]
+
+            assert result == [
+                {
+                    "range": {
+                        "end": {"character": 21, "line": 20},
+                        "start": {"character": 8, "line": 20},
+                    },
+                    "relativePath": "lib/features/add_meal/presentation/add_meal_screen.dart",
+                },
+                {
+                    "range": {
+                        "end": {"character": 21, "line": 23},
+                        "start": {"character": 8, "line": 23},
+                    },
+                    "relativePath": "lib/features/add_meal/presentation/add_meal_screen.dart",
+                },
+                {
+                    "range": {
+                        "end": {"character": 53, "line": 26},
+                        "start": {"character": 40, "line": 26},
+                    },
+                    "relativePath": "lib/features/add_meal/presentation/add_meal_screen.dart",
+                },
+            ]


Reviews:
user: login: LakshyAAAgrawal
body: Everything looks great! However, the unittests are currently failing possibly because dart was not found in the environment. We will need it to work in the CI. You can look at https://github.com/pratham1002/multilspy/blob/69373e057e75585f58b27c767b6f460f9954825e/.github/workflows/test-workflow.yaml#L15-L19 for reference.

I would prefer to the extent possible, that the lsp executable is downloaded in the setup_runtime_dependencies, and if and only if we determine that that will be infeasible/undesirable, then this route (of adding sections to set it up separately in the CI) can be taken.

What are your thoughts?
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-02-28T03:39:25Z
user: login: v4rgas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-01T23:14:34Z
user: login: LakshyAAAgrawal
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-03-01T23:44:00Z
user: login: LakshyAAAgrawal
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-03-01T23:45:56Z
user: login: v4rgas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-02T00:11:21Z
user: login: v4rgas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-02T00:13:05Z
user: login: v4rgas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-02T00:16:35Z
user: login: LakshyAAAgrawal
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-02T22:23:13Z
user: login: v4rgas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T03:16:28Z
user: login: LakshyAAAgrawal
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-03T03:33:48Z

Review comments:
path: tests/multilspy/test_sync_multilspy_dart.py
user: login: LakshyAAAgrawal
body: This is good to start with now, but can we maybe add tests for any other commonly used lsp features as well?
created_at: 2025-02-28T03:32:14Z
author_association: COLLABORATOR
path: src/multilspy/language_servers/dart_language_server/initialize_params.json
user: login: LakshyAAAgrawal
body: Is it possible to add some initialization options, that are good reasonable defaults from https://github.com/dart-lang/sdk/blob/master/pkg/analysis_server/tool/lsp_spec/README.md#initialization-options?
created_at: 2025-02-28T03:34:10Z
author_association: COLLABORATOR
path: src/multilspy/language_servers/dart_language_server/initialize_params.json
user: login: LakshyAAAgrawal
body: This will also serve as a reference point for people to understand what all can be configured in this
created_at: 2025-02-28T03:34:31Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,120 @@
+from contextlib import asynccontextmanager
+import logging
+import os
+import pathlib
+import shutil
+from typing import AsyncIterator
+from multilspy.language_server import LanguageServer
+from multilspy.lsp_protocol_handler.server import ProcessLaunchInfo
+import json
+
+
+class DartLanguageServer(LanguageServer):
+    """
+    Provides Dart specific instantiation of the LanguageServer class. Contains various configurations and settings specific to Dart.
+    """
+
+    def __init__(self, config, logger, repository_root_path):
+        """
+        Creates a DartServer instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
+        """
+
+        executable_path = self.setup_runtime_dependencies()
+        super().__init__(
+            config,
+            logger,
+            repository_root_path,
+            ProcessLaunchInfo(cmd=executable_path, cwd=repository_root_path),
+            "dart",
+        )
+
+    def setup_runtime_dependencies(self):
path: src/multilspy/language_servers/dart_language_server/dart_language_server.py
user: login: LakshyAAAgrawal
body: Is it possible/easy to download and setup automatically the dart lsp? My aim with multilspy is for it to be a batteries-included framework, users shouldnt have to worry about installing dependencies to the extent possible.

It is okay to keep it as it is, but just wanted your thoughts as well.
created_at: 2025-02-28T03:36:12Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,120 @@
+from contextlib import asynccontextmanager
+import logging
+import os
+import pathlib
+import shutil
+from typing import AsyncIterator
+from multilspy.language_server import LanguageServer
+from multilspy.lsp_protocol_handler.server import ProcessLaunchInfo
+import json
+
+
+class DartLanguageServer(LanguageServer):
+    """
+    Provides Dart specific instantiation of the LanguageServer class. Contains various configurations and settings specific to Dart.
+    """
+
+    def __init__(self, config, logger, repository_root_path):
+        """
+        Creates a DartServer instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
+        """
+
+        executable_path = self.setup_runtime_dependencies()
+        super().__init__(
+            config,
+            logger,
+            repository_root_path,
+            ProcessLaunchInfo(cmd=executable_path, cwd=repository_root_path),
+            "dart",
+        )
+
+    def setup_runtime_dependencies(self):
path: src/multilspy/language_servers/dart_language_server/dart_language_server.py
user: login: v4rgas
body: you are right, after some digging I found that it was not that hard to make it batteries included, i just commited this change

i do not own a windows or apple computer so i have no way to test if it works correctly, for this reason i only included linux
created_at: 2025-03-01T23:14:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,6 +23,9 @@ classifiers = [
     "Programming Language :: Python",
     "Programming Language :: Rust",
     "Programming Language :: JavaScript"
path: pyproject.toml
user: login: LakshyAAAgrawal
body: "," needs to be added at EOL
created_at: 2025-03-01T23:39:13Z
author_association: COLLABORATOR
path: src/multilspy/language_servers/dart_language_server/initialize_params.json
user: login: LakshyAAAgrawal
body: Do we also want to add a workspace configuration file https://github.com/dart-lang/sdk/blob/main/pkg/analysis_server/tool/lsp_spec/README.md#client-workspace-configuration? Could be useful, but can leave out for now if it is too much work.
created_at: 2025-03-01T23:43:26Z
author_association: COLLABORATOR
path: tests/multilspy/test_multilspy_dart.py
user: login: LakshyAAAgrawal
body: The filenaming convention I was trying to follow is to have test_{/sync_}multilspy_{langname}_{test_projname}. Could you please update to follow the same?
created_at: 2025-03-01T23:45:50Z
author_association: COLLABORATOR
path: tests/multilspy/test_multilspy_dart.py
user: login: v4rgas
body: what should be the name then? could u help me with that?
created_at: 2025-03-02T00:11:21Z
author_association: CONTRIBUTOR
path: src/multilspy/language_servers/dart_language_server/initialize_params.json
user: login: v4rgas
body: to be honest i do not know what that configuration is for, so i wouldnt be sure what to add exactly

would u mind sending me some docs or adding it yourself if possible?
created_at: 2025-03-02T00:13:05Z
author_association: CONTRIBUTOR
path: tests/multilspy/test_multilspy_dart.py
user: login: v4rgas
body: i changed it
created_at: 2025-03-02T00:16:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -22,7 +22,10 @@ classifiers = [
     "Programming Language :: Java",
     "Programming Language :: Python",
     "Programming Language :: Rust",
-    "Programming Language :: JavaScript"
+    "Programming Language :: JavaScript",
path: pyproject.toml
user: login: LakshyAAAgrawal
body: Thanks a lot for fixing the other names! Can you also add "Programming Language :: C#"
created_at: 2025-03-02T22:22:33Z
author_association: COLLABORATOR
diff_hunk: @@ -22,7 +22,10 @@ classifiers = [
     "Programming Language :: Java",
     "Programming Language :: Python",
     "Programming Language :: Rust",
-    "Programming Language :: JavaScript"
+    "Programming Language :: JavaScript",
path: pyproject.toml
user: login: v4rgas
body: its already there! its the first one
created_at: 2025-03-03T03:16:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -22,7 +22,10 @@ classifiers = [
     "Programming Language :: Java",
     "Programming Language :: Python",
     "Programming Language :: Rust",
-    "Programming Language :: JavaScript"
+    "Programming Language :: JavaScript",
path: pyproject.toml
user: login: LakshyAAAgrawal
body: My bad. When I see it in GitHub, it doesnt show the full context!
created_at: 2025-03-03T03:33:48Z
author_association: COLLABORATOR

PR comments:
user: login: LakshyAAAgrawal
created_at: 2025-02-28T03:42:45Z
body: Also please add the name "dart" in relevant places in the README! This is indeed a major contribution!
author_association: COLLABORATOR
user: login: LakshyAAAgrawal
created_at: 2025-03-02T22:24:15Z
body: Closes #53 
author_association: COLLABORATOR
user: login: LakshyAAAgrawal
created_at: 2025-03-03T01:25:06Z
body: LGTM! Thanks a lot for your contribution.

As next steps, I would request to create a few issues for things that this PR doesn't add, which would be desirable for Dart support (support in non-linux environments to automatically download and run the lsp, configuration options, etc.). I will merge this now unless you had any changes.
author_association: COLLABORATOR
user: login: v4rgas
created_at: 2025-03-03T03:17:48Z
body: sound good to me, i dont have any other changes for now but ill make sure to add a few more tests during the week

if you could help me with the initialization options thatd be great

thanks for all ur comments, ill open a new pr if i make any other changes
author_association: CONTRIBUTOR