Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
981150e308 | ||
|
|
6de2cc3867 | ||
|
|
1fefcb4cba |
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python: ["3.6", "3.7", "3.8", "3.9", "3.10"]
|
||||
python: ["3.7", "3.8", "3.9", "3.10"]
|
||||
os: [ubuntu-18.04, windows-2019]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -12,12 +12,11 @@ Alpha Stage, work in progress.
|
||||
## Features
|
||||
- [x] Builtin command completion
|
||||
- [x] Documentation for commands and variables on hover
|
||||
- [x] Formatting
|
||||
- [x] Formatting (by [`cmake-format`](https://github.com/cheshirekow/cmake_format))
|
||||
|
||||
## Commands
|
||||
|
||||
- `cmake-language-server`: LSP server
|
||||
- `python -m cmake_language_server.formatter`: CLI frontend for formatting
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
144
poetry.lock
generated
144
poetry.lock
generated
@@ -20,6 +20,21 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
|
||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
|
||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
|
||||
|
||||
[[package]]
|
||||
name = "cmakelang"
|
||||
version = "0.6.13"
|
||||
description = "Language tools for cmake (format, lint, etc)"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
six = ">=1.13.0"
|
||||
|
||||
[package.extras]
|
||||
yaml = ["pyyaml (>=5.3)"]
|
||||
html-gen = ["jinja2 (==2.10.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.4"
|
||||
@@ -39,14 +54,6 @@ python-versions = ">=3.6"
|
||||
[package.extras]
|
||||
toml = ["tomli"]
|
||||
|
||||
[[package]]
|
||||
name = "dataclasses"
|
||||
version = "0.8"
|
||||
description = "A backport of the dataclasses module for Python 3.6"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6, <3.7"
|
||||
|
||||
[[package]]
|
||||
name = "importlib-metadata"
|
||||
version = "4.8.3"
|
||||
@@ -108,45 +115,47 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "1.7.4"
|
||||
description = "Data validation and settings management using python 3.6 type hinting"
|
||||
version = "1.9.1"
|
||||
description = "Data validation and settings management using python type hints"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.6.1"
|
||||
|
||||
[package.dependencies]
|
||||
dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""}
|
||||
typing-extensions = ">=3.7.4.3"
|
||||
|
||||
[package.extras]
|
||||
dotenv = ["python-dotenv (>=0.10.4)"]
|
||||
email = ["email-validator (>=1.0.3)"]
|
||||
typing_extensions = ["typing-extensions (>=3.7.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "pygls"
|
||||
version = "0.11.3"
|
||||
version = "0.12"
|
||||
description = "a pythonic generic language server (pronounced like \"pie glass\")."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = "<3.11,>=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
pydantic = ">=1.7,<1.9"
|
||||
pydantic = ">=1.9.1,<1.10"
|
||||
typeguard = ">=2.10.0,<3"
|
||||
|
||||
[package.extras]
|
||||
dev = ["bandit (==1.6.0)", "flake8 (==3.7.7)", "mypy (==0.812)"]
|
||||
docs = ["sphinx (==2.0.1)", "sphinx-rtd-theme (==0.4.3)"]
|
||||
test = ["mock (==3.0.5)", "pytest (==4.5.0)", "pytest-asyncio (==0.10.0)"]
|
||||
ws = ["websockets (>=9.0.0,<10.0.0)"]
|
||||
dev = ["bandit (==1.7.4)", "flake8 (==4.0.1)", "mypy (==0.961)"]
|
||||
docs = ["sphinx (==5.0.1)", "sphinx-rtd-theme (==1.0.0)"]
|
||||
test = ["mock (==4.0.3)", "pytest (==7.1.2)", "pytest-asyncio (==0.18.3)"]
|
||||
ws = ["websockets (>=10.0.0,<11.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "2.4.7"
|
||||
version = "3.0.7"
|
||||
description = "Python parsing module"
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
diagrams = ["jinja2", "railroad-diagrams"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
@@ -197,6 +206,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
[package.dependencies]
|
||||
pytest = ">=2.7.0"
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.10.2"
|
||||
@@ -239,8 +256,8 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.6"
|
||||
content-hash = "8b534309919acadb4c5b088a7a9aff76066ab695b1d39bf507b32db898450b76"
|
||||
python-versions = "^3.7,<3.11"
|
||||
content-hash = "611ecc79e7246a5e3136e80b2b5937ee5a097866faaa2ad251e5143985c267a9"
|
||||
|
||||
[metadata.files]
|
||||
atomicwrites = [
|
||||
@@ -251,6 +268,10 @@ attrs = [
|
||||
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
|
||||
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
|
||||
]
|
||||
cmakelang = [
|
||||
{file = "cmakelang-0.6.13-py3-none-any.whl", hash = "sha256:764b9467195c7c36453d60a829f30229720d26c7dffd41cb516b99bd9c7daf4e"},
|
||||
{file = "cmakelang-0.6.13.tar.gz", hash = "sha256:03982e87b00654d024d73ef972d9d9bb0e5726cdb6b8a424a15661fb6278e67f"},
|
||||
]
|
||||
colorama = [
|
||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||
@@ -304,10 +325,6 @@ coverage = [
|
||||
{file = "coverage-6.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de"},
|
||||
{file = "coverage-6.2.tar.gz", hash = "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8"},
|
||||
]
|
||||
dataclasses = [
|
||||
{file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"},
|
||||
{file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"},
|
||||
]
|
||||
importlib-metadata = [
|
||||
{file = "importlib_metadata-4.8.3-py3-none-any.whl", hash = "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e"},
|
||||
{file = "importlib_metadata-4.8.3.tar.gz", hash = "sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668"},
|
||||
@@ -329,36 +346,49 @@ py = [
|
||||
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
||||
]
|
||||
pydantic = [
|
||||
{file = "pydantic-1.7.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3c60039e84552442defbcb5d56711ef0e057028ca7bfc559374917408a88d84e"},
|
||||
{file = "pydantic-1.7.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:6e7e314acb170e143c6f3912f93f2ec80a96aa2009ee681356b7ce20d57e5c62"},
|
||||
{file = "pydantic-1.7.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:8ef77cd17b73b5ba46788d040c0e820e49a2d80cfcd66fda3ba8be31094fd146"},
|
||||
{file = "pydantic-1.7.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:115d8aa6f257a1d469c66b6bfc7aaf04cd87c25095f24542065c68ebcb42fe63"},
|
||||
{file = "pydantic-1.7.4-cp36-cp36m-win_amd64.whl", hash = "sha256:66757d4e1eab69a3cfd3114480cc1d72b6dd847c4d30e676ae838c6740fdd146"},
|
||||
{file = "pydantic-1.7.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c92863263e4bd89e4f9cf1ab70d918170c51bd96305fe7b00853d80660acb26"},
|
||||
{file = "pydantic-1.7.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:3b8154babf30a5e0fa3aa91f188356763749d9b30f7f211fafb247d4256d7877"},
|
||||
{file = "pydantic-1.7.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:80cc46378505f7ff202879dcffe4bfbf776c15675028f6e08d1d10bdfbb168ac"},
|
||||
{file = "pydantic-1.7.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:dda60d7878a5af2d8560c55c7c47a8908344aa78d32ec1c02d742ede09c534df"},
|
||||
{file = "pydantic-1.7.4-cp37-cp37m-win_amd64.whl", hash = "sha256:4c1979d5cc3e14b35f0825caddea5a243dd6085e2a7539c006bc46997ef7a61a"},
|
||||
{file = "pydantic-1.7.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8857576600c32aa488f18d30833aa833b54a48e3bab3adb6de97e463af71f8f8"},
|
||||
{file = "pydantic-1.7.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1f86d4da363badb39426a0ff494bf1d8510cd2f7274f460eee37bdbf2fd495ec"},
|
||||
{file = "pydantic-1.7.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:3ea1256a9e782149381e8200119f3e2edea7cd6b123f1c79ab4bbefe4d9ba2c9"},
|
||||
{file = "pydantic-1.7.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:e28455b42a0465a7bf2cde5eab530389226ce7dc779de28d17b8377245982b1e"},
|
||||
{file = "pydantic-1.7.4-cp38-cp38-win_amd64.whl", hash = "sha256:47c5b1d44934375a3311891cabd450c150a31cf5c22e84aa172967bf186718be"},
|
||||
{file = "pydantic-1.7.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:00250e5123dd0b123ff72be0e1b69140e0b0b9e404d15be3846b77c6f1b1e387"},
|
||||
{file = "pydantic-1.7.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d24aa3f7f791a023888976b600f2f389d3713e4f23b7a4c88217d3fce61cdffc"},
|
||||
{file = "pydantic-1.7.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2c44a9afd4c4c850885436a4209376857989aaf0853c7b118bb2e628d4b78c4e"},
|
||||
{file = "pydantic-1.7.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:e87edd753da0ca1d44e308a1b1034859ffeab1f4a4492276bff9e1c3230db4fe"},
|
||||
{file = "pydantic-1.7.4-cp39-cp39-win_amd64.whl", hash = "sha256:a3026ee105b5360855e500b4abf1a1d0b034d88e75a2d0d66a4c35e60858e15b"},
|
||||
{file = "pydantic-1.7.4-py3-none-any.whl", hash = "sha256:a82385c6d5a77e3387e94612e3e34b77e13c39ff1295c26e3ba664e7b98073e2"},
|
||||
{file = "pydantic-1.7.4.tar.gz", hash = "sha256:0a1abcbd525fbb52da58c813d54c2ec706c31a91afdb75411a73dd1dec036595"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8098a724c2784bf03e8070993f6d46aa2eeca031f8d8a048dff277703e6e193"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c320c64dd876e45254bdd350f0179da737463eea41c43bacbee9d8c9d1021f11"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18f3e912f9ad1bdec27fb06b8198a2ccc32f201e24174cec1b3424dda605a310"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11951b404e08b01b151222a1cb1a9f0a860a8153ce8334149ab9199cd198131"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8bc541a405423ce0e51c19f637050acdbdf8feca34150e0d17f675e72d119580"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e565a785233c2d03724c4dc55464559639b1ba9ecf091288dd47ad9c629433bd"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:a4a88dcd6ff8fd47c18b3a3709a89adb39a6373f4482e04c1b765045c7e282fd"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:447d5521575f18e18240906beadc58551e97ec98142266e521c34968c76c8761"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:985ceb5d0a86fcaa61e45781e567a59baa0da292d5ed2e490d612d0de5796918"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059b6c1795170809103a1538255883e1983e5b831faea6558ef873d4955b4a74"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d12f96b5b64bec3f43c8e82b4aab7599d0157f11c798c9f9c528a72b9e0b339a"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ae72f8098acb368d877b210ebe02ba12585e77bd0db78ac04a1ee9b9f5dd2166"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:79b485767c13788ee314669008d01f9ef3bc05db9ea3298f6a50d3ef596a154b"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:494f7c8537f0c02b740c229af4cb47c0d39840b829ecdcfc93d91dcbb0779892"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0f047e11febe5c3198ed346b507e1d010330d56ad615a7e0a89fae604065a0e"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:969dd06110cb780da01336b281f53e2e7eb3a482831df441fb65dd30403f4608"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:177071dfc0df6248fd22b43036f936cfe2508077a72af0933d0c1fa269b18537"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9bcf8b6e011be08fb729d110f3e22e654a50f8a826b0575c7196616780683380"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a955260d47f03df08acf45689bd163ed9df82c0e0124beb4251b1290fa7ae728"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9ce157d979f742a915b75f792dbd6aa63b8eccaf46a1005ba03aa8a986bde34a"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0bf07cab5b279859c253d26a9194a8906e6f4a210063b84b433cf90a569de0c1"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d93d4e95eacd313d2c765ebe40d49ca9dd2ed90e5b37d0d421c597af830c195"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1542636a39c4892c4f4fa6270696902acb186a9aaeac6f6cf92ce6ae2e88564b"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a9af62e9b5b9bc67b2a195ebc2c2662fdf498a822d62f902bf27cccb52dbbf49"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fe4670cb32ea98ffbf5a1262f14c3e102cccd92b1869df3bb09538158ba90fe6"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:9f659a5ee95c8baa2436d392267988fd0f43eb774e5eb8739252e5a7e9cf07e0"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b83ba3825bc91dfa989d4eed76865e71aea3a6ca1388b59fc801ee04c4d8d0d6"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1dd8fecbad028cd89d04a46688d2fcc14423e8a196d5b0a5c65105664901f810"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02eefd7087268b711a3ff4db528e9916ac9aa18616da7bca69c1871d0b7a091f"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7eb57ba90929bac0b6cc2af2373893d80ac559adda6933e562dcfb375029acee"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4ce9ae9e91f46c344bec3b03d6ee9612802682c1551aaf627ad24045ce090761"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:72ccb318bf0c9ab97fc04c10c37683d9eea952ed526707fabf9ac5ae59b701fd"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:61b6760b08b7c395975d893e0b814a11cf011ebb24f7d869e7118f5a339a82e1"},
|
||||
{file = "pydantic-1.9.1-py3-none-any.whl", hash = "sha256:4988c0f13c42bfa9ddd2fe2f569c9d54646ce84adc5de84228cfe83396f3bd58"},
|
||||
{file = "pydantic-1.9.1.tar.gz", hash = "sha256:1ed987c3ff29fff7fd8c3ea3a3ea877ad310aae2ef9889a119e22d3f2db0691a"},
|
||||
]
|
||||
pygls = [
|
||||
{file = "pygls-0.11.3-py3-none-any.whl", hash = "sha256:5c925b182f2b0aa38d0ce83a9829ca5aed8eb9c7079cffc5bddff2da1033b58f"},
|
||||
{file = "pygls-0.11.3.tar.gz", hash = "sha256:4d86fc854e6d6613cd42bf7511e9c6aac947fc8d62ff973a705570b036d969f2"},
|
||||
{file = "pygls-0.12-py3-none-any.whl", hash = "sha256:93f8cd9458edb0cb8524588affa0f5fd7f75a4cdb5e2d450437b913e657df65b"},
|
||||
{file = "pygls-0.12.tar.gz", hash = "sha256:452586db4e153f67d3e0505ceb98234e2cf1425c882f089fd458271a721b7809"},
|
||||
]
|
||||
pyparsing = [
|
||||
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
|
||||
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
||||
{file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"},
|
||||
{file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"},
|
||||
]
|
||||
pytest = [
|
||||
{file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
|
||||
@@ -372,6 +402,10 @@ pytest-datadir = [
|
||||
{file = "pytest-datadir-1.3.1.tar.gz", hash = "sha256:d3af1e738df87515ee509d6135780f25a15959766d9c2b2dbe02bf4fb979cb18"},
|
||||
{file = "pytest_datadir-1.3.1-py2.py3-none-any.whl", hash = "sha256:1847ed0efe0bc54cac40ab3fba6d651c2f03d18dd01f2a582979604d32e7621e"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
]
|
||||
toml = [
|
||||
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
||||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "cmake-language-server"
|
||||
version = "0.1.4"
|
||||
version = "0.1.6"
|
||||
description = "CMake LSP Implementation"
|
||||
license = "MIT"
|
||||
authors = ["regen"]
|
||||
@@ -18,15 +18,15 @@ classifiers = [
|
||||
]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.6"
|
||||
pygls = "^0.11"
|
||||
pyparsing = "^2.4"
|
||||
python = "^3.7,<3.11"
|
||||
pygls = "^0.12"
|
||||
importlib-metadata = {version = "^4.8", python = "<3.8"}
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^6.2"
|
||||
pytest-datadir = "^1.3"
|
||||
pytest-cov = "^2.11"
|
||||
cmakelang = "^0.6.13"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
cmake-language-server = "cmake_language_server.server:main"
|
||||
@@ -45,7 +45,7 @@ enable_isort = true
|
||||
enable_mypy = true
|
||||
mypy_preset = "strict"
|
||||
line_length = 88
|
||||
py_version = "py36"
|
||||
py_version = "py37"
|
||||
|
||||
[[tool.pysen.lint.mypy_targets]]
|
||||
paths = ["."]
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from .parser import TokenList
|
||||
|
||||
|
||||
class Formatter(object):
|
||||
indent: str
|
||||
lower_identifier: bool
|
||||
|
||||
def __init__(self, indent: str = " ", lower_identifier: bool = True):
|
||||
self.indent = indent
|
||||
self.lower_identifier = lower_identifier
|
||||
|
||||
def format(self, tokens: TokenList) -> str:
|
||||
cmds: List[str] = [""]
|
||||
indent_level = 0
|
||||
for token in tokens:
|
||||
if isinstance(token, tuple):
|
||||
raw_identifier = token[0]
|
||||
identifier = raw_identifier.lower()
|
||||
if identifier in (
|
||||
"elseif",
|
||||
"else",
|
||||
"endif",
|
||||
"endforeach",
|
||||
"endwhile",
|
||||
"endmacro",
|
||||
"endfunction",
|
||||
):
|
||||
if indent_level > 0:
|
||||
indent_level -= 1
|
||||
cmds[-1] = self.indent * indent_level
|
||||
cmds[-1] += identifier if self.lower_identifier else raw_identifier
|
||||
args = self._format_args(token[1])
|
||||
if len(args) < 2:
|
||||
cmds[-1] += "(" + "".join(args) + ")"
|
||||
else:
|
||||
cmds[-1] += "(\n"
|
||||
for arg in args:
|
||||
cmds[-1] += self.indent * (indent_level + 1) + arg + "\n"
|
||||
cmds[-1] += self.indent * indent_level + ")"
|
||||
if identifier in (
|
||||
"if",
|
||||
"elseif",
|
||||
"else",
|
||||
"foreach",
|
||||
"while",
|
||||
"macro",
|
||||
"function",
|
||||
):
|
||||
indent_level += 1
|
||||
elif token == "\n":
|
||||
cmds.append("")
|
||||
elif token[0] == "#":
|
||||
if cmds[-1]:
|
||||
cmds[-1] += token
|
||||
else:
|
||||
cmds[-1] = self.indent * indent_level + token
|
||||
elif cmds[-1]:
|
||||
cmds[-1] += token
|
||||
|
||||
cmds = self._strip_line(cmds)
|
||||
return "\n".join(cmds) + "\n"
|
||||
|
||||
def _format_args(self, args: List[str]) -> List[str]:
|
||||
lines = [""]
|
||||
for i in range(len(args)):
|
||||
arg = args[i]
|
||||
if arg[0] == "#":
|
||||
lines[-1] += arg
|
||||
elif arg[0] == "\n":
|
||||
lines.append("")
|
||||
elif arg.isspace():
|
||||
if lines[-1]:
|
||||
if i + 1 < len(args) and args[i + 1][0] == "#":
|
||||
lines[-1] += arg
|
||||
else:
|
||||
lines[-1] += " "
|
||||
else:
|
||||
lines[-1] += arg
|
||||
|
||||
return self._strip_line(lines)
|
||||
|
||||
def _strip_line(self, lines: List[str]) -> List[str]:
|
||||
"""Delete empty lines at the start/end of the input"""
|
||||
|
||||
ret: List[str] = []
|
||||
for line in lines:
|
||||
line = line.rstrip()
|
||||
if line != "" or len(ret) > 0:
|
||||
ret.append(line)
|
||||
while ret and ret[-1] == "":
|
||||
del ret[-1]
|
||||
return ret
|
||||
|
||||
|
||||
def main(argss: Optional[List[str]] = None) -> None:
|
||||
import sys
|
||||
from argparse import ArgumentParser
|
||||
from difflib import unified_diff
|
||||
from pathlib import Path
|
||||
|
||||
from . import __version__
|
||||
from .parser import ListParser
|
||||
|
||||
parser = ArgumentParser(
|
||||
description="Format CMake list files.",
|
||||
epilog="""
|
||||
If no arguments are specified, it formats the code from
|
||||
standard input and writes the result to the standard output.""",
|
||||
)
|
||||
parser.add_argument("lists", type=Path, nargs="*", help="CMake list files")
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("-i", "--inplace", action="store_true", help="inplace edit")
|
||||
group.add_argument("-d", "--diff", action="store_true", help="show diff")
|
||||
parser.add_argument(
|
||||
"--version", action="version", version=f"%(prog)s {__version__}"
|
||||
)
|
||||
|
||||
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)
|
||||
return
|
||||
if not args.lists:
|
||||
args.lists.append(None)
|
||||
|
||||
list_parser = ListParser()
|
||||
formatter = Formatter()
|
||||
for listpath in args.lists:
|
||||
if listpath is None:
|
||||
listpath = "(stdin)"
|
||||
content = sys.stdin.read()
|
||||
else:
|
||||
with listpath.open() as fp:
|
||||
content = fp.read()
|
||||
tokens, remain = list_parser.parse(content)
|
||||
formatted = content if remain else formatter.format(tokens)
|
||||
|
||||
if args.inplace:
|
||||
if not remain:
|
||||
with listpath.open("w") as fp:
|
||||
fp.write(formatted)
|
||||
elif args.diff:
|
||||
diff = unified_diff(
|
||||
content.splitlines(True),
|
||||
formatted.splitlines(True),
|
||||
str(listpath),
|
||||
str(listpath),
|
||||
"(before formatting)",
|
||||
"(after formatting)",
|
||||
)
|
||||
diffstr = "".join(diff)
|
||||
print(diffstr, end="")
|
||||
else:
|
||||
print(formatted, end="")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,70 +0,0 @@
|
||||
from typing import List, Tuple, Union
|
||||
|
||||
import pyparsing as pp
|
||||
|
||||
CommandTokenType = Tuple[str, List[str]]
|
||||
TokenType = Union[str, CommandTokenType]
|
||||
TokenList = List[TokenType]
|
||||
|
||||
|
||||
class ListParser(object):
|
||||
_parser: pp.ParserElement
|
||||
|
||||
def __init__(self) -> None:
|
||||
newline = "\n"
|
||||
space_plus = pp.Regex("[ \t]+")
|
||||
space_star = pp.Optional(space_plus)
|
||||
|
||||
quoted_element = pp.Regex(r'[^\\"]|\\[^A-Za-z0-9]|\\[trn]')
|
||||
quoted_argument = pp.Combine('"' + pp.ZeroOrMore(quoted_element) + '"')
|
||||
|
||||
bracket_content = pp.Forward()
|
||||
|
||||
def action_bracket_open(tokens: pp.ParseResults) -> None:
|
||||
nonlocal bracket_content
|
||||
marker = "]" + "=" * (len(tokens[0]) - 2) + "]"
|
||||
bracket_content <<= pp.SkipTo(marker, include=True)
|
||||
|
||||
bracket_open = pp.Regex(r"\[=*\[").setParseAction(action_bracket_open)
|
||||
bracket_argument = pp.Combine(bracket_open + bracket_content)
|
||||
|
||||
unquoted_element = pp.Regex(r'[^\s()#"\\]|\\[^A-Za-z0-9]|\\[trn]')
|
||||
unquoted_argument = pp.Combine(pp.OneOrMore(unquoted_element))
|
||||
|
||||
argument = bracket_argument | quoted_argument | unquoted_argument
|
||||
|
||||
line_comment = pp.Combine("#" + ~bracket_open + pp.SkipTo(pp.LineEnd()))
|
||||
bracket_comment = pp.Combine("#" + bracket_argument)
|
||||
line_ending = (
|
||||
space_star
|
||||
+ pp.ZeroOrMore(bracket_comment + space_star)
|
||||
+ pp.Optional(line_comment)
|
||||
+ (newline | pp.lineEnd)
|
||||
)
|
||||
|
||||
identifier = pp.Word(pp.alphas + "_", pp.alphanums + "_")
|
||||
arguments = pp.Forward()
|
||||
(
|
||||
arguments
|
||||
<< pp.ZeroOrMore(
|
||||
argument | line_ending | space_plus | "(" + arguments + ")"
|
||||
).leaveWhitespace()
|
||||
)
|
||||
arguments = pp.Group(arguments)
|
||||
PAREN_L, PAREN_R = map(pp.Suppress, "()")
|
||||
command_invocation = (
|
||||
identifier + space_star.suppress() + PAREN_L + arguments + PAREN_R
|
||||
).setParseAction(lambda t: (t[0], t[1].asList()))
|
||||
|
||||
file_element = (
|
||||
space_star + command_invocation + line_ending | line_ending
|
||||
).leaveWhitespace()
|
||||
file = pp.ZeroOrMore(file_element)
|
||||
|
||||
self._parser = file
|
||||
|
||||
def parse(self, liststr: str) -> Tuple[TokenList, str]:
|
||||
for t, s, e in self._parser.scanString(liststr, maxMatches=1):
|
||||
if s == 0:
|
||||
return t.asList(), liststr[e:]
|
||||
return [], liststr
|
||||
@@ -1,5 +1,7 @@
|
||||
import logging
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, List, Optional, Tuple
|
||||
|
||||
@@ -32,20 +34,16 @@ from pygls.lsp.types import (
|
||||
from pygls.server import LanguageServer
|
||||
|
||||
from .api import API
|
||||
from .formatter import Formatter
|
||||
from .parser import ListParser
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CMakeLanguageServer(LanguageServer):
|
||||
_parser: ListParser
|
||||
_api: Optional[API]
|
||||
|
||||
def __init__(self, *args: Any) -> None:
|
||||
super().__init__(*args)
|
||||
|
||||
self._parser = ListParser()
|
||||
self._api = None
|
||||
|
||||
@self.feature(INITIALIZE)
|
||||
@@ -151,26 +149,30 @@ class CMakeLanguageServer(LanguageServer):
|
||||
|
||||
return CompletionList(is_incomplete=False, items=items)
|
||||
|
||||
@self.feature(FORMATTING)
|
||||
def formatting(params: DocumentFormattingParams) -> Optional[List[TextEdit]]:
|
||||
doc = self.workspace.get_document(params.text_document.uri)
|
||||
content = doc.source
|
||||
tokens, remain = self._parser.parse(content)
|
||||
if remain:
|
||||
self.show_message("CMake parser failed")
|
||||
return None
|
||||
if shutil.which("cmake-format") is not None:
|
||||
|
||||
formatted = Formatter().format(tokens)
|
||||
lines = content.count("\n")
|
||||
return [
|
||||
TextEdit(
|
||||
range=Range(
|
||||
start=Position(line=0, character=0),
|
||||
end=Position(line=lines + 1, character=0),
|
||||
),
|
||||
new_text=formatted,
|
||||
@self.feature(FORMATTING)
|
||||
def formatting(
|
||||
params: DocumentFormattingParams,
|
||||
) -> Optional[List[TextEdit]]:
|
||||
doc = self.workspace.get_document(params.text_document.uri)
|
||||
content = doc.source
|
||||
formatted = subprocess.check_output(
|
||||
["cmake-format", "-"],
|
||||
cwd=str(Path(doc.path).parent),
|
||||
input=content,
|
||||
universal_newlines=True,
|
||||
)
|
||||
]
|
||||
lines = content.count("\n")
|
||||
return [
|
||||
TextEdit(
|
||||
range=Range(
|
||||
start=Position(line=0, character=0),
|
||||
end=Position(line=lines + 1, character=0),
|
||||
),
|
||||
new_text=formatted,
|
||||
)
|
||||
]
|
||||
|
||||
@self.feature(HOVER)
|
||||
def hover(params: TextDocumentPositionParams) -> Optional[Hover]:
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
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) -> Callable[[], None]:
|
||||
def test() -> None:
|
||||
tokens, remain = ListParser().parse(liststr)
|
||||
actual = Formatter().format(tokens)
|
||||
assert actual == expect
|
||||
|
||||
return test
|
||||
|
||||
|
||||
test_command = make_formatter_test("a()", "a()\n")
|
||||
test_command_tolower = make_formatter_test("A()", "a()\n")
|
||||
test_remove_space = make_formatter_test(
|
||||
"""
|
||||
#a
|
||||
b ( c ) # d
|
||||
""",
|
||||
"""\
|
||||
#a
|
||||
b(c) # d
|
||||
""",
|
||||
)
|
||||
test_indent_if = make_formatter_test(
|
||||
"""
|
||||
if()
|
||||
a() # a
|
||||
else()
|
||||
# b
|
||||
b()
|
||||
endif()
|
||||
""",
|
||||
"""\
|
||||
if()
|
||||
a() # a
|
||||
else()
|
||||
# b
|
||||
b()
|
||||
endif()
|
||||
""",
|
||||
)
|
||||
test_indent_if_nested = make_formatter_test(
|
||||
"""
|
||||
if()
|
||||
if()
|
||||
a()
|
||||
b()
|
||||
endif()
|
||||
endif()
|
||||
""",
|
||||
"""\
|
||||
if()
|
||||
if()
|
||||
a()
|
||||
b()
|
||||
endif()
|
||||
endif()
|
||||
""",
|
||||
)
|
||||
test_argument = make_formatter_test("a( b c d)", "a(b c d)\n")
|
||||
test_argument_multiline = make_formatter_test(
|
||||
"""
|
||||
if()
|
||||
a(b c
|
||||
d # e
|
||||
f
|
||||
# g
|
||||
) # h
|
||||
endif()
|
||||
""",
|
||||
"""\
|
||||
if()
|
||||
a(
|
||||
b c
|
||||
d # e
|
||||
f
|
||||
# g
|
||||
) # h
|
||||
endif()
|
||||
""",
|
||||
)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def mock_stdin(buf: str) -> Iterator[None]:
|
||||
stdin = sys.stdin
|
||||
sys.stdin = StringIO(buf)
|
||||
yield
|
||||
sys.stdin = stdin
|
||||
|
||||
|
||||
def test_main_stdin(capsys: CaptureFixture[str]) -> None:
|
||||
with mock_stdin(" a()"):
|
||||
main([])
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "a()\n"
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
def test_main_stdin_diff(capsys: CaptureFixture[str]) -> None:
|
||||
with mock_stdin(" a()"):
|
||||
main(["-d"])
|
||||
captured = capsys.readouterr()
|
||||
assert "- a()" in captured.out
|
||||
assert "+a()" in captured.out
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
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()")
|
||||
|
||||
main([str(testfile1)])
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "a()\n"
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
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()")
|
||||
testfile2 = tmp_path / "list2.cmake"
|
||||
with testfile2.open("w") as fp:
|
||||
fp.write(" b()")
|
||||
|
||||
main([str(testfile1), str(testfile2)])
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "a()\nb()\n"
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
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()")
|
||||
|
||||
main(["-i", str(testfile1)])
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == ""
|
||||
assert captured.err == ""
|
||||
|
||||
with testfile1.open() as fp:
|
||||
content = fp.read()
|
||||
assert content == "a()\n"
|
||||
|
||||
|
||||
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()")
|
||||
|
||||
main(["-d", str(testfile1)])
|
||||
captured = capsys.readouterr()
|
||||
assert str(testfile1) in captured.out
|
||||
assert "- a()" in captured.out
|
||||
assert "+a()" in captured.out
|
||||
assert captured.err == ""
|
||||
@@ -1,83 +0,0 @@
|
||||
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 = ""
|
||||
) -> Callable[[], None]:
|
||||
def test() -> None:
|
||||
actual_token, actual_remain = ListParser().parse(liststr)
|
||||
assert actual_token == expect_token
|
||||
assert actual_remain == expect_remain
|
||||
|
||||
return test
|
||||
|
||||
|
||||
test_command_no_args = make_parser_test("a()", [("a", [])])
|
||||
test_command_space = make_parser_test(" a ()", [" ", ("a", [])])
|
||||
test_command_arg = make_parser_test("a(b)", [("a", ["b"])])
|
||||
test_command_arg_space = make_parser_test("a ( b )", [("a", ["b"])])
|
||||
test_command_arg_escape = make_parser_test(r"a(\n\")", [("a", [r"\n\""])])
|
||||
test_command_arg_paren = make_parser_test("a((b))", [("a", ["(", "b", ")"])])
|
||||
test_command_arg_paren_paren = make_parser_test(
|
||||
"a(((b)))", [("a", ["(", "(", "b", ")", ")"])]
|
||||
)
|
||||
test_command_arg_quote = make_parser_test(r'a("b\"")', [("a", [r'"b\""'])])
|
||||
test_command_arg_quote_cont = make_parser_test('a("\\\n")', [("a", ['"\\\n"'])])
|
||||
test_command_arg_quo_multiline = make_parser_test(
|
||||
"""a("b
|
||||
c
|
||||
")""",
|
||||
[("a", ['"b\nc\n"'])],
|
||||
)
|
||||
test_command_arg_bracket_0 = make_parser_test("a([[b]])", [("a", ["[[b]]"])])
|
||||
test_command_arg_bracket_1 = make_parser_test("a([=[b]=])", [("a", ["[=[b]=]"])])
|
||||
test_command_arg_space = make_parser_test("a ( b )", [("a", [" ", "b", " "])])
|
||||
test_command_arg_multi = make_parser_test("a(b c)", [("a", ["b", " ", "c"])])
|
||||
test_command_multielement = make_parser_test(
|
||||
"""a(
|
||||
b
|
||||
c # c
|
||||
)""",
|
||||
[("a", ["\n", " ", "b", "\n", " ", "c", " ", "# c", "\n"])],
|
||||
)
|
||||
test_line_comment = make_parser_test("a() # b # c", [("a", []), " ", "# b # c"])
|
||||
test_bracket_comment = make_parser_test("#[[a]]#[[b]]", ["#[[a]]", "#[[b]]"])
|
||||
test_bracket_comment_nested = make_parser_test("#[=[[[a]]]=]", ["#[=[[[a]]]=]"])
|
||||
test_bracket_comment_multiline = make_parser_test(
|
||||
"#[[\na\nb\nc\n]]", ["#[[\na\nb\nc\n]]"]
|
||||
)
|
||||
test_if_block = make_parser_test(
|
||||
"""if()
|
||||
a()
|
||||
else()
|
||||
b()
|
||||
endif()""",
|
||||
[
|
||||
("if", []),
|
||||
"\n",
|
||||
" ",
|
||||
("a", []),
|
||||
"\n",
|
||||
("else", []),
|
||||
"\n",
|
||||
" ",
|
||||
("b", []),
|
||||
"\n",
|
||||
("endif", []),
|
||||
],
|
||||
)
|
||||
test_comment_multi_linecomment = make_parser_test(
|
||||
"""a()# a
|
||||
b() # b
|
||||
c() # c""",
|
||||
[("a", []), "# a", "\n", ("b", []), " ", "# b", "\n", ("c", []), " ", "# c"],
|
||||
)
|
||||
|
||||
test_incomplete_id = make_parser_test("a", [], "a")
|
||||
test_incomplete_command = make_parser_test("a(", [], "a(")
|
||||
test_incomplete_id_after_command = make_parser_test("a()\nb", [("a", []), "\n"], "b")
|
||||
test_incomplete_command_after_command = make_parser_test(
|
||||
"a()\nb(c", [("a", []), "\n"], "b(c"
|
||||
)
|
||||
Reference in New Issue
Block a user