Esempio n. 1
0
 def lsp_renames(self) -> Iterator[RenameFile]:
     """Get all File rename operations."""
     for old_name, new_name in self.refactoring.get_renames():
         yield RenameFile(
             old_uri=from_fs_path(old_name),
             new_uri=from_fs_path(new_name),
             options=RenameFileOptions(
                 ignore_if_exists=True, overwrite=True
             ),
         )
Esempio n. 2
0
    def get_location(self, location: str) -> Tuple[str, Optional[int]]:

        if not location:
            conf = pathlib.Path(self.app.confdir, "conf.py")
            return (str(conf), None)

        path, *parts = location.split(":")
        lineno = None

        # On windows the rest of the path will be the first element of parts
        if IS_WIN:
            path += f":{parts.pop(0)}"

        if len(parts) == 1:
            try:
                lineno = int(parts[0])
            except ValueError:
                pass

        if len(parts) == 2:
            # TODO: There's a possibility that there is an error in a docstring in a
            #       *.py file somewhere. In which case parts would look like
            #       ['docstring of {dotted.name}', '{lineno}']
            #
            #  e.g. ['docstring of esbonio.lsp.sphinx.SphinxLanguageServer.get_domains', '8']
            #
            #       It would be good to handle this case and look up the correct line
            #       number to place a diagnostic.
            pass

        return (Uri.from_fs_path(path), lineno)
Esempio n. 3
0
def exception_to_diagnostic(exc: BaseException):
    """Convert an exception into a diagnostic we can send to the client."""

    # Config errors sometimes wrap the true cause of the problem
    if isinstance(exc, ConfigError) and exc.__cause__ is not None:
        exc = exc.__cause__

    if isinstance(exc, SyntaxError):
        path = pathlib.Path(exc.filename or "")
        line = (exc.lineno or 1) - 1
    else:
        tb = exc.__traceback__
        frame = traceback.extract_tb(tb)[-1]
        path = pathlib.Path(frame.filename)
        line = (frame.lineno or 1) - 1

    message = type(exc).__name__ if exc.args.count == 0 else exc.args[0]

    diagnostic = Diagnostic(
        range=Range(
            start=Position(line=line, character=0),
            end=Position(line=line + 1, character=0),
        ),
        message=message,
        severity=DiagnosticSeverity.Error,
    )

    return Uri.from_fs_path(str(path)), diagnostic
Esempio n. 4
0
    def lsp_initialize(self, params: InitializeParams) -> InitializeResult:
        """Method that initializes language server.
        It will compute and return server capabilities based on
        registered features.
        """
        logger.info('Language server initialized %s', params)

        self._server.process_id = params.process_id

        # Initialize server capabilities
        self.client_capabilities = params.capabilities
        self.server_capabilities = ServerCapabilitiesBuilder(
            self.client_capabilities,
            {**self.fm.features, **self.fm.builtin_features}.keys(),
            self.fm.feature_options,
            list(self.fm.commands.keys()),
            self._server.sync_kind,
        ).build()
        logger.debug('Server capabilities: %s', self.server_capabilities.dict())

        root_path = params.root_path
        root_uri = params.root_uri or from_fs_path(root_path)

        # Initialize the workspace
        workspace_folders = params.workspace_folders or []
        self.workspace = Workspace(root_uri, self._server.sync_kind, workspace_folders)

        self.trace = Trace.Off

        return InitializeResult(capabilities=self.server_capabilities)
Esempio n. 5
0
    def ref_definition(self, label: str) -> List[Location]:
        """Goto definition implementation for ``:ref:`` targets"""

        if not self.rst.app or not self.rst.app.env:
            return []

        types = set(self.rst.get_role_target_types("ref"))
        std = self.rst.get_domain("std")
        if std is None:
            return []

        docname = self.find_docname_for_label(label, std, types)
        if docname is None:
            return []

        path = self.rst.app.env.doc2path(docname)
        uri = Uri.from_fs_path(path)

        doctree = self.rst.get_initial_doctree(uri)
        if doctree is None:
            return []

        uri = None
        line = None

        for node in doctree.traverse(condition=nodes.target):

            if "refid" not in node:
                continue

            if doctree.nameids.get(label, "") == node["refid"]:
                uri = Uri.from_fs_path(node.source)
                line = node.line
                break

        if uri is None or line is None:
            return []

        return [
            Location(
                uri=uri,
                range=Range(
                    start=Position(line=line - 1, character=0),
                    end=Position(line=line, character=0),
                ),
            )
        ]
Esempio n. 6
0
def _get_locations(defs: List[Name]) -> List[types.Location]:
    return [
        types.Location(
            from_fs_path(d.module_path),
            types.Range(types.Position(d.line - 1, d.column),
                        types.Position(d.line - 1, d.column + len(d.name))))
        for d in defs if d.module_path
    ]
Esempio n. 7
0
def normalise_uri(uri: str) -> str:

    uri = Uri.from_fs_path(Uri.to_fs_path(uri))

    # Paths on windows are case insensitive.
    if IS_WIN:
        uri = uri.lower()

    return uri
Esempio n. 8
0
 def lsp_text_document_edits(self) -> Iterator[TextDocumentEdit]:
     """Get all text document edits."""
     changed_files = self.refactoring.get_changed_files()
     for path, changed_file in changed_files.items():
         uri = from_fs_path(path)
         text_edits = lsp_text_edits(changed_file)
         yield TextDocumentEdit(
             text_document=VersionedTextDocumentIdentifier(
                 uri=uri,
                 version=None,  # type: ignore
             ),
             edits=text_edits,
         )
Esempio n. 9
0
def _get_document_changes(
        ls: LanguageServer,
        refactoring: Refactoring) -> List[types.TextDocumentEdit]:
    result = []
    for fn, changes in refactoring.get_changed_files().items():
        text_edits = _get_text_edits(changes)
        if text_edits:
            uri = from_fs_path(fn)
            result.append(
                types.TextDocumentEdit(
                    types.VersionedTextDocumentIdentifier(
                        uri,
                        ls.workspace.get_document(uri).version), text_edits))
    return result
Esempio n. 10
0
    def resolve_doc(self, doc: Document, label: str) -> Optional[str]:

        if self.rst.app is None:
            return None

        srcdir = self.rst.app.srcdir
        currentdir = pathlib.Path(Uri.to_fs_path(doc.uri)).parent

        if label.startswith("/"):
            path = pathlib.Path(srcdir, label[1:] + ".rst")
        else:
            path = pathlib.Path(currentdir, label + ".rst")

        if not path.exists():
            return None

        return Uri.from_fs_path(str(path))
Esempio n. 11
0
 def read_error_file(self, path: str):
     with open(path, "r") as jsfile:
         data = json.load(jsfile)
         for file, content in data.items():
             uri = from_fs_path(file)
             for severity_label, record_list in content.items():
                 severity = DiagnosticSeverity.Error
                 # To change if we have something else than error
                 for r in record_list:
                     position = Position(line=r["line"],
                                         character=r["column"])
                     diagnostic = Diagnostic(
                         range=Range(start=position, end=position),
                         message="Parse error : rejected token.  ",
                         source="Verible Syntax",
                         code="syntax-error",
                         severity=severity)
                     logger.info(f"Register error {uri}:{r['line']}")
                     self._register_diagnostic(uri, diagnostic)
Esempio n. 12
0
    def resolve_path(self, doc: Document, argument: str) -> Optional[str]:

        if argument.startswith("/"):
            if not self.rst.app:
                return None

            basedir = pathlib.Path(self.rst.app.srcdir)

            # Remove the leading '/' otherwise is will wipe out the basedir when
            # concatenated
            argument = argument[1:]

        else:
            basedir = pathlib.Path(Uri.to_fs_path(doc.uri)).parent

        fpath = (basedir / argument).resolve()
        if not fpath.exists():
            return None

        return Uri.from_fs_path(str(fpath))
Esempio n. 13
0
def get_references(doc: Dict[str, str], symbol: str) -> List[Location]:
    """Given a representation of a document and a symbol string, return the
    Location of every use of that symbol within the document."""
    current_line = 0
    output = []
    symbol_len = len(symbol)
    uri = from_fs_path(doc["path"])
    for line in doc["source"].split("\n"):
        for index in [
                i for i in range(len(line)) if line.startswith(symbol, i)
        ]:
            output.append(
                Location(
                    uri=uri,
                    range=Range(
                        start=Position(line=current_line, character=index),
                        end=Position(line=current_line,
                                     character=index + symbol_len),
                    ),
                ))

        current_line += 1
    return output
Esempio n. 14
0
def sourcepos2position(pos: birdeec.SourcePos,
                       main_src_uri: str) -> (Position, str):
    if not pos: return None
    uri = from_fs_path(
        pos.source_path) if pos.source_idx != -1 else main_src_uri
    return (Position(pos.line - 1, pos.pos - 1), uri)
Esempio n. 15
0
    def resolve_build_dir(self, root_uri: str,
                          actual_conf_dir: str) -> pathlib.Path:
        """Get the build dir to use based on the user's config.

        If nothing is specified in the given ``config``, this will choose a location
        within the user's cache dir (as determined by
        `appdirs <https://pypi.org/project/appdirs>`). The directory name will be a hash
        derived from the given ``conf_dir`` for the project.

        Alternatively the user (or least language client) can override this by setting
        either an absolute path, or a path based on the following "variables".

        - ``${workspaceRoot}`` which expands to the workspace root as provided
          by the language client.

        - ``${workspaceFolder}`` alias for ``${workspaceRoot}``, placeholder ready for
          multi-root support.

        - ``${confDir}`` which expands to the configured config dir.

        Parameters
        ----------
        root_uri
           The workspace root uri

        actual_conf_dir:
           The fully resolved conf dir for the project
        """

        if not self.build_dir:
            # Try to pick a sensible dir based on the project's location
            cache = appdirs.user_cache_dir("esbonio", "swyddfa")
            project = hashlib.md5(str(actual_conf_dir).encode()).hexdigest()

            return pathlib.Path(cache) / project

        root_dir = Uri.to_fs_path(root_uri)
        match = PATH_VAR_PATTERN.match(self.build_dir)

        if match and match.group(1) in {"workspaceRoot", "workspaceFolder"}:
            build = pathlib.Path(self.build_dir).parts[1:]
            return pathlib.Path(root_dir, *build).resolve()

        if match and match.group(1) == "confDir":
            build = pathlib.Path(self.build_dir).parts[1:]
            return pathlib.Path(actual_conf_dir, *build).resolve()

        # Convert path to/from uri so that any path quirks from windows are
        # automatically handled
        build_uri = Uri.from_fs_path(self.build_dir)
        build_dir = Uri.to_fs_path(build_uri)

        # But make sure paths starting with '~' are not corrupted
        if build_dir.startswith("/~"):
            build_dir = build_dir.replace("/~", "~")

        # But make sure (windows) paths starting with '~' are not corrupted
        if build_dir.startswith("\\~"):
            build_dir = build_dir.replace("\\~", "~")

        return pathlib.Path(build_dir).expanduser()
Esempio n. 16
0
def test_get_missing_document(tmpdir, workspace):
    doc_path = tmpdir.join("test_document.py")
    doc_path.write(DOC_TEXT)
    doc_uri = uris.from_fs_path(str(doc_path))
    assert workspace.get_document(doc_uri).source == DOC_TEXT
Esempio n. 17
0
def lsp_location(name: Name) -> Location:
    """Get LSP location from Jedi definition."""
    return Location(uri=from_fs_path(name.module_path), range=lsp_range(name))
Esempio n. 18
0
def workspace(tmpdir):
    """Return a workspace."""
    return Workspace(uris.from_fs_path(str(tmpdir)), Mock())
Esempio n. 19
0
#                                                                          #
#     http: // www.apache.org/licenses/LICENSE-2.0                         #
#                                                                          #
# Unless required by applicable law or agreed to in writing, software      #
# distributed under the License is distributed on an "AS IS" BASIS,        #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and      #
# limitations under the License.                                           #
############################################################################
import os

from pygls import uris
from pygls.types import TextDocumentItem, WorkspaceFolder
from pygls.workspace import Workspace

DOC_URI = uris.from_fs_path(__file__)
DOC_TEXT = '''test'''
DOC = TextDocumentItem(DOC_URI, 'plaintext', 0, DOC_TEXT)


def test_add_folder(workspace):
    dir_uri = os.path.dirname(DOC_URI)
    dir_name = 'test'
    workspace.add_folder(WorkspaceFolder(dir_uri, dir_name))
    assert workspace.folders[dir_uri].name == dir_name


def test_get_document(workspace):
    workspace.put_document(DOC)

    assert workspace.get_document(DOC_URI).source == DOC_TEXT
Esempio n. 20
0
def initialize_server(server):
    server.lsp.bf_initialize(
        InitializeParams(process_id=1234,
                         capabilities=ClientCapabilities(),
                         root_uri=from_fs_path(WORKSPACE_PATH)))
Esempio n. 21
0
 def run_incremental(self, files: T.Optional[T.List[str]] = None):
     for f in files:
         if f not in self.filelist:
             self.filelist.append(f)
         self.clear_file(from_fs_path(f))
     self._run(incr=True, force_fset=files)
Esempio n. 22
0
	def path(self,val):
		self._path = uris.from_fs_path(os.path.abspath(os.path.join(self.root_path,val)))
Esempio n. 23
0
    def _(*args, **kwargs):
        ...

    @client.feature("esbonio/buildComplete")
    def _(*args, **kwargs):
        ...

    return client


@pytest_lsp.fixture(
    scope="session",
    config=[
        ClientServerConfig(
            client="visual_studio_code",
            client_factory=make_esbonio_client,
            server_command=[sys.executable, "-m", "esbonio"],
            root_uri=uri.from_fs_path(str(root_path)),
        ),
        ClientServerConfig(
            client="neovim",
            client_factory=make_esbonio_client,
            server_command=[sys.executable, "-m", "esbonio"],
            root_uri=uri.from_fs_path(str(root_path)),
        ),
    ],
)
async def client(client_: Client):
    # Wait for the server to initialize.
    await client_.wait_for_notification("esbonio/buildComplete")
Esempio n. 24
0
def test_win_from_fs_path(path, uri):
    assert uris.from_fs_path(path) == uri