Replace linter (#37)
This commit is contained in:
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
poetry.lock linguist-generated=true
|
||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
python: [3.6, 3.7, 3.8]
|
||||
python: [3.6, 3.7, 3.8, 3.9]
|
||||
os: [ubuntu-18.04, windows-2016]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
129
.gitignore
vendored
129
.gitignore
vendored
@@ -1,133 +1,4 @@
|
||||
### https://raw.github.com/github/gitignore/cb0c6ef7ac68f2300409ee85501d9ad432cb4c7e/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
[style]
|
||||
based_on_style = pep8
|
||||
6
mypy.ini
6
mypy.ini
@@ -1,6 +0,0 @@
|
||||
[mypy]
|
||||
ignore_missing_imports = True
|
||||
allow_redefinition = True
|
||||
|
||||
[mypy-re.Scanner]
|
||||
ignore_errors = True
|
||||
754
poetry.lock
generated
754
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -23,14 +23,10 @@ pygls = "^0.8.1"
|
||||
pyparsing = "^2.4"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
flake8 = "^3.7"
|
||||
mypy = "^0.740.0"
|
||||
pytest = "^5.2"
|
||||
pytest = "^6.2"
|
||||
pytest-datadir = "^1.3"
|
||||
tox = "^3.14"
|
||||
isort = "^4.3"
|
||||
pytest-cov = "^2.8"
|
||||
black = "^19.10b0"
|
||||
pytest-cov = "^2.11"
|
||||
pysen = {version = "^0.9", extras = ["lint"]}
|
||||
|
||||
[tool.poetry.scripts]
|
||||
cmake-format = "cmake_language_server.formatter:main"
|
||||
@@ -39,3 +35,18 @@ cmake-language-server = "cmake_language_server.server:main"
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.pysen]
|
||||
version = "0.9"
|
||||
|
||||
[tool.pysen.lint]
|
||||
enable_black = true
|
||||
enable_flake8 = true
|
||||
enable_isort = true
|
||||
enable_mypy = true
|
||||
mypy_preset = "strict"
|
||||
line_length = 88
|
||||
py_version = "py36"
|
||||
|
||||
[[tool.pysen.lint.mypy_targets]]
|
||||
paths = ["."]
|
||||
|
||||
@@ -25,7 +25,7 @@ class API(object):
|
||||
_uuid: uuid.UUID
|
||||
_builtin_commands: Dict[str, str]
|
||||
_builtin_variables: Dict[str, str]
|
||||
_builtin_variable_template: Dict[Pattern, str]
|
||||
_builtin_variable_template: Dict[Pattern[str], str]
|
||||
_builtin_modules: Dict[str, str]
|
||||
_targets: List[str]
|
||||
_cached_variables: Dict[str, str]
|
||||
@@ -45,7 +45,7 @@ class API(object):
|
||||
self._generated_list_parsed = False
|
||||
|
||||
def query(self) -> bool:
|
||||
""" Use CMake's file API to get JSON information about the build tree
|
||||
"""Use CMake's file API to get JSON information about the build tree
|
||||
|
||||
Generates a JSON request file for the current build tree and runs
|
||||
CMake on the build tree. Deletes the request file immediately
|
||||
@@ -83,7 +83,7 @@ class API(object):
|
||||
return True
|
||||
|
||||
def read_reply(self) -> bool:
|
||||
""" Reads the CMake file API reply file and updates internal state
|
||||
"""Reads the CMake file API reply file and updates internal state
|
||||
|
||||
Reads the result of the previous query file and updates
|
||||
the targets, the cache entries and the cmake files.
|
||||
@@ -112,13 +112,13 @@ class API(object):
|
||||
|
||||
return True
|
||||
|
||||
def _read_codemodel(self, codemodelpath: Path):
|
||||
def _read_codemodel(self, codemodelpath: Path) -> None:
|
||||
with (codemodelpath).open() as fp:
|
||||
codemodel = json.load(fp)
|
||||
config = codemodel["configurations"][0]
|
||||
self._targets[:] = [x["name"] for x in config["targets"]]
|
||||
|
||||
def _read_cache(self, cachepath: Path):
|
||||
def _read_cache(self, cachepath: Path) -> None:
|
||||
with cachepath.open() as fp:
|
||||
cache = json.load(fp)
|
||||
self._cached_variables.clear()
|
||||
@@ -134,7 +134,7 @@ class API(object):
|
||||
doc.append(f"`{value}`")
|
||||
self._cached_variables[name] = "\n\n".join(doc)
|
||||
|
||||
def _read_cmake_files(self, jsonpath: Path):
|
||||
def _read_cmake_files(self, jsonpath: Path) -> None:
|
||||
"""inspect CMake list files that are used during build generation"""
|
||||
|
||||
if not self._builtin_variables or self._generated_list_parsed:
|
||||
@@ -214,7 +214,7 @@ endforeach()
|
||||
self._parse_modules()
|
||||
|
||||
def _parse_commands(self) -> None:
|
||||
""" Load docs for builtin cmake functions
|
||||
"""Load docs for builtin cmake functions
|
||||
|
||||
Loads the documentation for builtin cmake functions from the result
|
||||
of `$ cmake --help-commands`.
|
||||
@@ -247,7 +247,7 @@ endforeach()
|
||||
self._builtin_commands[command] = "```cmake\n" + signature + "\n```"
|
||||
|
||||
def _parse_variables(self) -> None:
|
||||
""" Load docs for builtin cmake variables
|
||||
"""Load docs for builtin cmake variables
|
||||
|
||||
Loads the documentation for builtin cmake variables from
|
||||
the result of `$ cmake --help-variables`.
|
||||
@@ -286,7 +286,7 @@ endforeach()
|
||||
self._builtin_variables[variable] = doc
|
||||
|
||||
def _parse_modules(self) -> None:
|
||||
""" Loads docs for all modules in the cmake distribution
|
||||
"""Loads docs for all modules in the cmake distribution
|
||||
|
||||
Loads the documentation for cmake modules included in the
|
||||
distribution from the result of `$ cmake --help-modules`.
|
||||
@@ -316,7 +316,7 @@ endforeach()
|
||||
module = match.group("module")
|
||||
header = match.group("header")
|
||||
doc = _tidy_doc(match.group("doc"))
|
||||
if header is not None and header != "Overview":
|
||||
if header != "Overview":
|
||||
doc = ""
|
||||
self._builtin_modules[module] = doc
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
from .parser import TokenList
|
||||
|
||||
@@ -7,7 +7,7 @@ class Formatter(object):
|
||||
indent: str
|
||||
lower_identifier: bool
|
||||
|
||||
def __init__(self, indent=" ", lower_identifier=True):
|
||||
def __init__(self, indent: str = " ", lower_identifier: bool = True):
|
||||
self.indent = indent
|
||||
self.lower_identifier = lower_identifier
|
||||
|
||||
@@ -94,7 +94,7 @@ class Formatter(object):
|
||||
return ret
|
||||
|
||||
|
||||
def main(args: List[str] = None):
|
||||
def main(argss: Optional[List[str]] = None) -> None:
|
||||
import sys
|
||||
from argparse import ArgumentParser
|
||||
from difflib import unified_diff
|
||||
@@ -117,7 +117,7 @@ def main(args: List[str] = None):
|
||||
"--version", action="version", version=f"%(prog)s {__version__}"
|
||||
)
|
||||
|
||||
args = parser.parse_args(args)
|
||||
args = parser.parse_args(argss)
|
||||
|
||||
if not args.lists and args.inplace:
|
||||
print("error: cannot use -i when no arguments are specified.", file=sys.stderr)
|
||||
|
||||
@@ -10,7 +10,7 @@ TokenList = List[TokenType]
|
||||
class ListParser(object):
|
||||
_parser: pp.ParserElement
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self) -> None:
|
||||
newline = "\n"
|
||||
space_plus = pp.Regex("[ \t]+")
|
||||
space_star = pp.Optional(space_plus)
|
||||
@@ -20,7 +20,7 @@ class ListParser(object):
|
||||
|
||||
bracket_content = pp.Forward()
|
||||
|
||||
def action_bracket_open(tokens: pp.ParseResults):
|
||||
def action_bracket_open(tokens: pp.ParseResults) -> None:
|
||||
nonlocal bracket_content
|
||||
marker = "]" + "=" * (len(tokens[0]) - 2) + "]"
|
||||
bracket_content <<= pp.SkipTo(marker, include=True)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import logging
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Tuple
|
||||
from typing import Any, Callable, List, Optional, Tuple
|
||||
|
||||
from pygls.features import (
|
||||
COMPLETION,
|
||||
@@ -36,18 +36,18 @@ from .parser import ListParser
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CMakeLanguageServer(LanguageServer):
|
||||
class CMakeLanguageServer(LanguageServer): # type: ignore
|
||||
_parser: ListParser
|
||||
_api: API
|
||||
_api: Optional[API]
|
||||
|
||||
def __init__(self, *args):
|
||||
def __init__(self, *args: Any) -> None:
|
||||
super().__init__(*args)
|
||||
|
||||
self._parser = ListParser()
|
||||
self._api = None
|
||||
|
||||
@self.feature(INITIALIZE)
|
||||
def initialize(params: InitializeParams):
|
||||
def initialize(params: InitializeParams) -> None:
|
||||
opts = params.initializationOptions
|
||||
|
||||
cmake = getattr(opts, "cmakeExecutable", "cmake")
|
||||
@@ -60,7 +60,9 @@ class CMakeLanguageServer(LanguageServer):
|
||||
trigger_characters = ["{", "("]
|
||||
|
||||
@self.feature(COMPLETION, trigger_characters=trigger_characters)
|
||||
def completions(params: CompletionParams):
|
||||
def completions(params: CompletionParams) -> CompletionList:
|
||||
assert self._api is not None
|
||||
|
||||
if (
|
||||
hasattr(params, "context")
|
||||
and params.context.triggerKind == CompletionTriggerKind.TriggerCharacter
|
||||
@@ -143,7 +145,7 @@ class CMakeLanguageServer(LanguageServer):
|
||||
return CompletionList(False, items)
|
||||
|
||||
@self.feature(FORMATTING)
|
||||
def formatting(params: DocumentFormattingParams):
|
||||
def formatting(params: DocumentFormattingParams) -> Optional[List[TextEdit]]:
|
||||
doc = self.workspace.get_document(params.textDocument.uri)
|
||||
content = doc.source
|
||||
tokens, remain = self._parser.parse(content)
|
||||
@@ -156,16 +158,19 @@ class CMakeLanguageServer(LanguageServer):
|
||||
return [TextEdit(Range(Position(0, 0), Position(lines + 1, 0)), formatted)]
|
||||
|
||||
@self.feature(HOVER)
|
||||
def hover(params: TextDocumentPositionParams):
|
||||
def hover(params: TextDocumentPositionParams) -> Optional[Hover]:
|
||||
assert self._api is not None
|
||||
api = self._api
|
||||
|
||||
word = self._cursor_word(params.textDocument.uri, params.position, True)
|
||||
if not word:
|
||||
return None
|
||||
|
||||
candidates = [
|
||||
lambda x: self._api.get_command_doc(x.lower()),
|
||||
lambda x: self._api.get_variable_doc(x),
|
||||
lambda x: self._api.get_module_doc(x, False),
|
||||
lambda x: self._api.get_module_doc(x, True),
|
||||
candidates: List[Callable[[str], Optional[str]]] = [
|
||||
lambda x: api.get_command_doc(x.lower()),
|
||||
lambda x: api.get_variable_doc(x),
|
||||
lambda x: api.get_module_doc(x, False),
|
||||
lambda x: api.get_module_doc(x, True),
|
||||
]
|
||||
for c in candidates:
|
||||
doc = c(word[0])
|
||||
@@ -177,7 +182,9 @@ class CMakeLanguageServer(LanguageServer):
|
||||
@self.thread()
|
||||
@self.feature(TEXT_DOCUMENT_DID_SAVE, includeText=False)
|
||||
@self.feature(INITIALIZED)
|
||||
def run_cmake(*args):
|
||||
def run_cmake(*args: Any) -> None:
|
||||
assert self._api is not None
|
||||
|
||||
if self._api.query():
|
||||
self._api.read_reply()
|
||||
|
||||
@@ -192,7 +199,7 @@ class CMakeLanguageServer(LanguageServer):
|
||||
doc = self.workspace.get_document(uri)
|
||||
content = doc.source
|
||||
line = content.split("\n")[position.line]
|
||||
return line
|
||||
return str(line)
|
||||
|
||||
def _cursor_word(
|
||||
self, uri: str, position: Position, include_all: bool = True
|
||||
@@ -212,7 +219,7 @@ class CMakeLanguageServer(LanguageServer):
|
||||
return None
|
||||
|
||||
|
||||
def main(args=None):
|
||||
def main() -> None:
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from . import __version__
|
||||
@@ -221,7 +228,7 @@ def main(args=None):
|
||||
parser.add_argument(
|
||||
"--version", action="version", version=f"%(prog)s {__version__}"
|
||||
)
|
||||
args = parser.parse_args(args)
|
||||
parser.parse_args()
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.getLogger("pygls").setLevel(logging.WARNING)
|
||||
|
||||
@@ -2,18 +2,19 @@ import asyncio
|
||||
import logging
|
||||
import os
|
||||
import pprint
|
||||
from pathlib import Path
|
||||
from subprocess import PIPE, run
|
||||
from threading import Thread
|
||||
from typing import Iterable, Tuple
|
||||
|
||||
import pytest
|
||||
from cmake_language_server.server import CMakeLanguageServer
|
||||
from pygls import features
|
||||
from pygls.server import LanguageServer
|
||||
|
||||
from cmake_language_server.server import CMakeLanguageServer
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def cmake_build(shared_datadir):
|
||||
def cmake_build(shared_datadir: Path) -> Iterable[Path]:
|
||||
source = shared_datadir / "cmake"
|
||||
build = source / "build"
|
||||
build.mkdir()
|
||||
@@ -33,11 +34,11 @@ def cmake_build(shared_datadir):
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def client_server():
|
||||
def client_server() -> Iterable[Tuple[LanguageServer, CMakeLanguageServer]]:
|
||||
c2s_r, c2s_w = os.pipe()
|
||||
s2c_r, s2c_w = os.pipe()
|
||||
|
||||
def start(ls: LanguageServer, fdr, fdw):
|
||||
def start(ls: LanguageServer, fdr: int, fdw: int) -> None:
|
||||
# TODO: better patch is needed
|
||||
# disable `close()` to avoid error messages
|
||||
close = ls.loop.close
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from cmake_language_server.api import API
|
||||
|
||||
|
||||
def test_query_with_cache(cmake_build):
|
||||
def test_query_with_cache(cmake_build: Path) -> None:
|
||||
api = API("cmake", cmake_build)
|
||||
assert api.query()
|
||||
|
||||
@@ -14,14 +15,14 @@ def test_query_with_cache(cmake_build):
|
||||
assert reply.exists()
|
||||
|
||||
|
||||
def test_query_without_cache(cmake_build):
|
||||
def test_query_without_cache(cmake_build: Path) -> None:
|
||||
api = API("cmake", cmake_build)
|
||||
(cmake_build / "CMakeCache.txt").unlink()
|
||||
|
||||
assert not api.query()
|
||||
|
||||
|
||||
def test_read_variable(cmake_build):
|
||||
def test_read_variable(cmake_build: Path) -> None:
|
||||
api = API("cmake", cmake_build)
|
||||
assert api.query()
|
||||
assert api.read_reply()
|
||||
@@ -29,7 +30,7 @@ def test_read_variable(cmake_build):
|
||||
assert api.get_variable_doc("testproject_BINARY_DIR")
|
||||
|
||||
|
||||
def test_read_cmake_files(cmake_build):
|
||||
def test_read_cmake_files(cmake_build: Path) -> None:
|
||||
api = API("cmake", cmake_build)
|
||||
api.parse_doc()
|
||||
assert api.query()
|
||||
@@ -48,7 +49,7 @@ def test_read_cmake_files(cmake_build):
|
||||
raise RuntimeError("Unexpected system")
|
||||
|
||||
|
||||
def test_parse_commands(cmake_build):
|
||||
def test_parse_commands(cmake_build: Path) -> None:
|
||||
api = API("cmake", cmake_build)
|
||||
api.parse_doc()
|
||||
|
||||
@@ -67,7 +68,7 @@ def test_parse_commands(cmake_build):
|
||||
assert api.get_command_doc("not_existing_command") is None
|
||||
|
||||
|
||||
def test_parse_variables(cmake_build):
|
||||
def test_parse_variables(cmake_build: Path) -> None:
|
||||
api = API("cmake", cmake_build)
|
||||
api.parse_doc()
|
||||
|
||||
@@ -88,7 +89,7 @@ def test_parse_variables(cmake_build):
|
||||
assert api.get_variable_doc("not_existing_variable") is None
|
||||
|
||||
|
||||
def test_parse_modules(cmake_build):
|
||||
def test_parse_modules(cmake_build: Path) -> None:
|
||||
api = API("cmake", cmake_build)
|
||||
api.parse_doc()
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
from typing import Callable, Iterator
|
||||
|
||||
from cmake_language_server.formatter import Formatter, main
|
||||
from cmake_language_server.parser import ListParser
|
||||
from pytest import CaptureFixture
|
||||
|
||||
|
||||
def make_formatter_test(liststr: str, expect: str):
|
||||
def test():
|
||||
def make_formatter_test(liststr: str, expect: str) -> Callable[[], None]:
|
||||
def test() -> None:
|
||||
tokens, remain = ListParser().parse(liststr)
|
||||
actual = Formatter().format(tokens)
|
||||
assert actual == expect
|
||||
@@ -88,14 +91,14 @@ endif()
|
||||
|
||||
|
||||
@contextmanager
|
||||
def mock_stdin(buf: str):
|
||||
def mock_stdin(buf: str) -> Iterator[None]:
|
||||
stdin = sys.stdin
|
||||
sys.stdin = StringIO(buf)
|
||||
yield
|
||||
sys.stdin = stdin
|
||||
|
||||
|
||||
def test_main_stdin(capsys):
|
||||
def test_main_stdin(capsys: CaptureFixture[str]) -> None:
|
||||
with mock_stdin(" a()"):
|
||||
main([])
|
||||
captured = capsys.readouterr()
|
||||
@@ -103,7 +106,7 @@ def test_main_stdin(capsys):
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
def test_main_stdin_diff(capsys):
|
||||
def test_main_stdin_diff(capsys: CaptureFixture[str]) -> None:
|
||||
with mock_stdin(" a()"):
|
||||
main(["-d"])
|
||||
captured = capsys.readouterr()
|
||||
@@ -112,7 +115,7 @@ def test_main_stdin_diff(capsys):
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
def test_main_file_1(capsys, tmp_path):
|
||||
def test_main_file_1(capsys: CaptureFixture[str], tmp_path: Path) -> None:
|
||||
testfile1 = tmp_path / "list1.cmake"
|
||||
with testfile1.open("w") as fp:
|
||||
fp.write(" a()")
|
||||
@@ -123,7 +126,7 @@ def test_main_file_1(capsys, tmp_path):
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
def test_main_file_2(capsys, tmp_path):
|
||||
def test_main_file_2(capsys: CaptureFixture[str], tmp_path: Path) -> None:
|
||||
testfile1 = tmp_path / "list1.cmake"
|
||||
with testfile1.open("w") as fp:
|
||||
fp.write(" a()")
|
||||
@@ -137,7 +140,7 @@ def test_main_file_2(capsys, tmp_path):
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
def test_main_inplace(capsys, tmp_path):
|
||||
def test_main_inplace(capsys: CaptureFixture[str], tmp_path: Path) -> None:
|
||||
testfile1 = tmp_path / "list1.cmake"
|
||||
with testfile1.open("w") as fp:
|
||||
fp.write(" a()")
|
||||
@@ -152,7 +155,7 @@ def test_main_inplace(capsys, tmp_path):
|
||||
assert content == "a()\n"
|
||||
|
||||
|
||||
def test_main_diff(capsys, tmp_path):
|
||||
def test_main_diff(capsys: CaptureFixture[str], tmp_path: Path) -> None:
|
||||
testfile1 = tmp_path / "list1.cmake"
|
||||
with testfile1.open("w") as fp:
|
||||
fp.write(" a()")
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
from typing import List
|
||||
from typing import Callable, List
|
||||
|
||||
from cmake_language_server.parser import ListParser, TokenType
|
||||
|
||||
|
||||
def make_parser_test(
|
||||
liststr: str, expect_token: List[TokenType], expect_remain: str = ""
|
||||
):
|
||||
def test():
|
||||
) -> Callable[[], None]:
|
||||
def test() -> None:
|
||||
actual_token, actual_remain = ListParser().parse(liststr)
|
||||
assert actual_token == expect_token
|
||||
assert actual_remain == expect_remain
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from concurrent import futures
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from cmake_language_server.server import CMakeLanguageServer
|
||||
from pygls.features import (
|
||||
COMPLETION,
|
||||
FORMATTING,
|
||||
@@ -12,6 +13,7 @@ from pygls.features import (
|
||||
from pygls.server import LanguageServer
|
||||
from pygls.types import (
|
||||
CompletionContext,
|
||||
CompletionList,
|
||||
CompletionParams,
|
||||
CompletionTriggerKind,
|
||||
DidOpenTextDocumentParams,
|
||||
@@ -27,7 +29,7 @@ from pygls.types import (
|
||||
CALL_TIMEOUT = 2
|
||||
|
||||
|
||||
def _init(client: LanguageServer, root: Path):
|
||||
def _init(client: LanguageServer, root: Path) -> None:
|
||||
retry = 3
|
||||
while retry > 0:
|
||||
try:
|
||||
@@ -43,7 +45,7 @@ def _init(client: LanguageServer, root: Path):
|
||||
break
|
||||
|
||||
|
||||
def _open(client: LanguageServer, path: Path, text: Optional[str] = None):
|
||||
def _open(client: LanguageServer, path: Path, text: Optional[str] = None) -> None:
|
||||
if text is None:
|
||||
with open(path) as fp:
|
||||
text = fp.read()
|
||||
@@ -55,8 +57,11 @@ def _open(client: LanguageServer, path: Path, text: Optional[str] = None):
|
||||
|
||||
|
||||
def _test_completion(
|
||||
client_server, datadir, content: str, context: Optional[CompletionContext]
|
||||
):
|
||||
client_server: Tuple[LanguageServer, CMakeLanguageServer],
|
||||
datadir: Path,
|
||||
content: str,
|
||||
context: Optional[CompletionContext],
|
||||
) -> CompletionList:
|
||||
client, server = client_server
|
||||
_init(client, datadir)
|
||||
path = datadir / "CMakeLists.txt"
|
||||
@@ -70,7 +75,9 @@ def _test_completion(
|
||||
return client.lsp.send_request(COMPLETION, params).result(timeout=CALL_TIMEOUT)
|
||||
|
||||
|
||||
def test_initialize(client_server, datadir):
|
||||
def test_initialize(
|
||||
client_server: Tuple[LanguageServer, CMakeLanguageServer], datadir: Path
|
||||
) -> None:
|
||||
client, server = client_server
|
||||
|
||||
assert server._api is None
|
||||
@@ -78,7 +85,9 @@ def test_initialize(client_server, datadir):
|
||||
assert server._api is not None
|
||||
|
||||
|
||||
def test_completions_invoked(client_server, datadir):
|
||||
def test_completions_invoked(
|
||||
client_server: Tuple[LanguageServer, CMakeLanguageServer], datadir: Path
|
||||
) -> None:
|
||||
response = _test_completion(
|
||||
client_server,
|
||||
datadir,
|
||||
@@ -90,14 +99,18 @@ def test_completions_invoked(client_server, datadir):
|
||||
assert "<PROJECT-NAME>" in item.documentation
|
||||
|
||||
|
||||
def test_completions_nocontext(client_server, datadir):
|
||||
def test_completions_nocontext(
|
||||
client_server: Tuple[LanguageServer, CMakeLanguageServer], datadir: Path
|
||||
) -> None:
|
||||
response = _test_completion(client_server, datadir, "projec", None)
|
||||
item = next(filter(lambda x: x.label == "project", response.items), None)
|
||||
assert item is not None
|
||||
assert "<PROJECT-NAME>" in item.documentation
|
||||
|
||||
|
||||
def test_completions_triggercharacter_variable(client_server, datadir):
|
||||
def test_completions_triggercharacter_variable(
|
||||
client_server: Tuple[LanguageServer, CMakeLanguageServer], datadir: Path
|
||||
) -> None:
|
||||
response = _test_completion(
|
||||
client_server,
|
||||
datadir,
|
||||
@@ -110,7 +123,9 @@ def test_completions_triggercharacter_variable(client_server, datadir):
|
||||
assert response == response_nocontext
|
||||
|
||||
|
||||
def test_completions_triggercharacter_module(client_server, datadir):
|
||||
def test_completions_triggercharacter_module(
|
||||
client_server: Tuple[LanguageServer, CMakeLanguageServer], datadir: Path
|
||||
) -> None:
|
||||
response = _test_completion(
|
||||
client_server,
|
||||
datadir,
|
||||
@@ -123,7 +138,9 @@ def test_completions_triggercharacter_module(client_server, datadir):
|
||||
assert response == response_nocontext
|
||||
|
||||
|
||||
def test_completions_triggercharacter_package(client_server, datadir):
|
||||
def test_completions_triggercharacter_package(
|
||||
client_server: Tuple[LanguageServer, CMakeLanguageServer], datadir: Path
|
||||
) -> None:
|
||||
response = _test_completion(
|
||||
client_server,
|
||||
datadir,
|
||||
@@ -136,7 +153,9 @@ def test_completions_triggercharacter_package(client_server, datadir):
|
||||
assert response == response_nocontext
|
||||
|
||||
|
||||
def test_formatting(client_server, datadir):
|
||||
def test_formatting(
|
||||
client_server: Tuple[LanguageServer, CMakeLanguageServer], datadir: Path
|
||||
) -> None:
|
||||
client, server = client_server
|
||||
_init(client, datadir)
|
||||
path = datadir / "CMakeLists.txt"
|
||||
@@ -150,7 +169,9 @@ def test_formatting(client_server, datadir):
|
||||
assert response[0].newText == "a(b c)\n"
|
||||
|
||||
|
||||
def test_hover(client_server, datadir):
|
||||
def test_hover(
|
||||
client_server: Tuple[LanguageServer, CMakeLanguageServer], datadir: Path
|
||||
) -> None:
|
||||
client, server = client_server
|
||||
_init(client, datadir)
|
||||
path = datadir / "CMakeLists.txt"
|
||||
|
||||
27
tox.ini
27
tox.ini
@@ -1,25 +1,15 @@
|
||||
[isort]
|
||||
multi_line_output = 3
|
||||
include_trailing_comma = True
|
||||
force_grid_wrap = 0
|
||||
use_parentheses = True
|
||||
ensure_newline_before_comments = True
|
||||
line_length = 88
|
||||
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = E203, W503
|
||||
|
||||
[tox]
|
||||
isolated_build = True
|
||||
skipsdist = True
|
||||
envlist = py36, py37, py38, lint
|
||||
envlist = py36, py37, py38, py39, lint
|
||||
allowlist_externals = git
|
||||
|
||||
[gh-actions]
|
||||
python =
|
||||
3.6: py36
|
||||
3.7: py37, lint
|
||||
3.8: py38
|
||||
3.7: py37
|
||||
3.8: py38, lint
|
||||
3.9: py39
|
||||
|
||||
[testenv]
|
||||
whitelist_externals = poetry
|
||||
@@ -32,7 +22,6 @@ commands =
|
||||
|
||||
[testenv:lint]
|
||||
commands =
|
||||
poetry run isort -c -rc src tests
|
||||
poetry run black --diff src tests
|
||||
poetry run flake8 src tests
|
||||
poetry run mypy src tests
|
||||
poetry run pysen run format
|
||||
git diff --exit-code --ignore-submodules
|
||||
poetry run pysen run lint
|
||||
|
||||
Reference in New Issue
Block a user