mirror of
https://github.com/mtshiba/pylyzer.git
synced 2025-07-07 17:45:00 +00:00
initial commit
This commit is contained in:
commit
20472bfb3c
21 changed files with 1930 additions and 0 deletions
13
.github/FUNDING.yml
vendored
Normal file
13
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: mtshiba # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
989
Cargo.lock
generated
Normal file
989
Cargo.lock
generated
Normal file
|
@ -0,0 +1,989 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "ascii-canvas"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff8eb72df928aafb99fe5d37b383f2fe25bd2a765e3e5f7c365916b6f2463a29"
|
||||
dependencies = [
|
||||
"term",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "docopt"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f3f119846c823f9eafcf953a8f6ffb6ed69bf6240883261a7f13b634579a51f"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"serde",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||
|
||||
[[package]]
|
||||
name = "els"
|
||||
version = "0.1.11"
|
||||
source = "git+https://github.com/erg-lang/erg-language-server?branch=main#be627c99faf539e8ad58f77eb41f8e76b759e6ab"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"erg_compiler",
|
||||
"lsp-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ena"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8944dc8fa28ce4a38f778bd46bf7d923fe73eed5a439398507246c8e017e6f36"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "erg_common"
|
||||
version = "0.6.0-beta.2"
|
||||
source = "git+https://github.com/erg-lang/erg?branch=main#2e289f7cd1503778293fa8c927df03825f6ef69b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "erg_compiler"
|
||||
version = "0.6.0-beta.2"
|
||||
source = "git+https://github.com/erg-lang/erg?branch=main#2e289f7cd1503778293fa8c927df03825f6ef69b"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"erg_parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "erg_parser"
|
||||
version = "0.6.0-beta.2"
|
||||
source = "git+https://github.com/erg-lang/erg?branch=main#2e289f7cd1503778293fa8c927df03825f6ef69b"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"unicode-xid 0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64dc3698e75d452867d9bd86f4a723f452ce9d01fe1d55990b79f0c790aa67db"
|
||||
dependencies = [
|
||||
"ascii-canvas",
|
||||
"atty",
|
||||
"bit-set",
|
||||
"diff",
|
||||
"docopt",
|
||||
"ena",
|
||||
"itertools",
|
||||
"lalrpop-util",
|
||||
"petgraph",
|
||||
"regex",
|
||||
"regex-syntax",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"sha2",
|
||||
"string_cache",
|
||||
"term",
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop-util"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c277d18683b36349ab5cd030158b54856fca6bb2d5dc5263b06288f486958b7c"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lsp-types"
|
||||
version = "0.93.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be6e9c7e2d18f651974370d7aff703f9513e0df6e464fd795660edc77e6ca51"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "ordermap"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"ordermap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.7.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.7.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "precomputed-hash"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "py2erg"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"erg_compiler",
|
||||
"rustpython-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pype"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"els",
|
||||
"erg_common",
|
||||
"erg_compiler",
|
||||
"py2erg",
|
||||
"rustpython-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg",
|
||||
"rand_xorshift",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
dependencies = [
|
||||
"cloudabi",
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"blake2b_simd",
|
||||
"constant_time_eq",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython-parser"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d85b1038ecd8791bdae455ae784b48f522ebeca1b3323d0af2b251c5c8ff1c68"
|
||||
dependencies = [
|
||||
"lalrpop",
|
||||
"lalrpop-util",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"unic-emoji-char",
|
||||
"unic-ucd-ident",
|
||||
"unicode_names2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.150"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.150"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89c058a82f9fd69b1becf8c274f412281038877c553182f1d02eb027045a2d67"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"new_debug_unreachable",
|
||||
"phf_shared",
|
||||
"precomputed-hash",
|
||||
"serde",
|
||||
"string_cache_codegen",
|
||||
"string_cache_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache_codegen"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0f45ed1b65bf9a4bf2f7b7dc59212d1926e9eaf00fa998988e420fd124467c6"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"string_cache_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache_shared"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"dirs",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "unic-char-property"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
|
||||
dependencies = [
|
||||
"unic-char-range",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-char-range"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
|
||||
|
||||
[[package]]
|
||||
name = "unic-common"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
|
||||
|
||||
[[package]]
|
||||
name = "unic-emoji-char"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b07221e68897210270a38bde4babb655869637af0f69407f96053a34f76494d"
|
||||
dependencies = [
|
||||
"unic-char-property",
|
||||
"unic-char-range",
|
||||
"unic-ucd-version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-ucd-ident"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987"
|
||||
dependencies = [
|
||||
"unic-char-property",
|
||||
"unic-char-range",
|
||||
"unic-ucd-version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-ucd-version"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
|
||||
dependencies = [
|
||||
"unic-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_names2"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87d6678d7916394abad0d4b19df4d3802e1fd84abd7d701f39b75ee71b9e8cf1"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
19
Cargo.toml
Normal file
19
Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
|||
[package]
|
||||
name = "pype"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "A Python static code analyzer & language server"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"crates/py2erg",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
rustpython-parser = "0.1.2"
|
||||
erg_compiler = { git = "https://github.com/erg-lang/erg", branch = "main" }
|
||||
erg_common = { git = "https://github.com/erg-lang/erg", branch = "main" }
|
||||
els = { git = "https://github.com/erg-lang/erg-language-server", branch = "main" }
|
||||
py2erg = { path = "./crates/py2erg" }
|
19
LICENSE
Normal file
19
LICENSE
Normal file
|
@ -0,0 +1,19 @@
|
|||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
38
README.md
Normal file
38
README.md
Normal file
|
@ -0,0 +1,38 @@
|
|||
# pype
|
||||
|
||||
`pype` is a Python static code analyzer & language server written in Rust.
|
||||
|
||||
## Installation
|
||||
|
||||
### cargo (rust package manager)
|
||||
|
||||
```bash
|
||||
cargo install pype
|
||||
```
|
||||
|
||||
or download the binary from [the releases page].
|
||||
|
||||
## How it works
|
||||
|
||||
pype uses the type checker of [the erg programming language](https://erg-lang.org) internally.
|
||||
This language is a transpiled language that targets Python, and has a static type system.
|
||||
|
||||
pype converts Python ASTs to Erg ASTs and passes them to Erg's type checker. It then displays the results with appropriate modifications.
|
||||
|
||||
## What is the advantage over pylint, pyright, pytype, etc.?
|
||||
|
||||
pype performs type inference of Python source code. Therefore, there is no need to annotate or type your Python scripts in order to use pype. You can, however, explicitly request type checks by specifying types.
|
||||
|
||||
Other softwares that takes the same approach as pype are pytype, pyright, etc.
|
||||
|
||||
However, pype is superior to them in the following points:
|
||||
|
||||
* Checking speed: pype can inspect Python scripts on average 100 times faster than pytype. This is largely due to the fact that pype is implemented in Rust, whereas pytype is implemented in Python.
|
||||
|
||||
|
||||
|
||||
* Type checking accuracy: pytype is just a static code analysis tool in python, whereas pype appropriates the type checker of Erg, a real statically typed programming language.
|
||||
|
||||
|
||||
|
||||
* Reporting quality: While pytype's error reports are frankly very crude, showing only that an error has occurred, pype shows where the error occurred and provides clear error messages. Also, pytype only displays the first error when there are multiple errors. pype enumerates as many errors as possible.
|
15
crates/py2erg/Cargo.toml
Normal file
15
crates/py2erg/Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "py2erg"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "A Python -> Erg converter"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rustpython-parser = "0.1.2"
|
||||
erg_compiler = { git = "https://github.com/erg-lang/erg", branch = "main" }
|
||||
erg_common = { git = "https://github.com/erg-lang/erg", branch = "main" }
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
343
crates/py2erg/convert.rs
Normal file
343
crates/py2erg/convert.rs
Normal file
|
@ -0,0 +1,343 @@
|
|||
use erg_common::traits::Stream;
|
||||
use rustpython_parser::ast::{StatementType, ExpressionType, Located, Program, Number, StringGroup, Operator, BooleanOperator, UnaryOperator, Suite, Parameters, Parameter};
|
||||
use rustpython_parser::ast::Location as PyLocation;
|
||||
|
||||
use erg_common::set::Set as HashSet;
|
||||
use erg_compiler::erg_parser::token::{Token, TokenKind, EQUAL, COLON};
|
||||
use erg_compiler::erg_parser::ast::{
|
||||
Expr, Module, Signature, VarSignature, VarPattern, Params, Identifier, VarName, DefBody, DefId, Block, Def, Literal, Args, PosArg, Accessor,
|
||||
BinOp, Lambda, LambdaSignature, TypeBoundSpecs, TypeSpec, SubrSignature, Decorator, NonDefaultParamSignature, DefaultParamSignature, ParamPattern, TypeSpecWithOp,
|
||||
Tuple, NormalTuple, Array, NormalArray, Set, NormalSet, Dict, NormalDict, PreDeclTypeSpec, SimpleTypeSpec, ConstArgs, AttrDef, UnaryOp, KeyValue, Dummy
|
||||
};
|
||||
|
||||
fn add_procedural_mark(name: String) -> String {
|
||||
match &name[..] {
|
||||
"print" => "print!".to_string(),
|
||||
"input" => "input!".to_string(),
|
||||
"open" => "open!".to_string(),
|
||||
"int" => "Int".to_string(),
|
||||
"float" => "Float".to_string(),
|
||||
"str" => "Str".to_string(),
|
||||
"bool" => "Bool".to_string(),
|
||||
"list" => "GenericArray".to_string(),
|
||||
"tuple" => "GenericTuple".to_string(),
|
||||
"range" => "Range".to_string(),
|
||||
_ => name,
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_attr(name: String, loc: PyLocation) -> Identifier {
|
||||
let token = Token::new(TokenKind::Symbol, add_procedural_mark(name), loc.row(), loc.column() - 1);
|
||||
let name = VarName::new(token);
|
||||
let dot = Token::new(TokenKind::Dot, ".", loc.row(), loc.column());
|
||||
Identifier::new(Some(dot), name)
|
||||
}
|
||||
|
||||
fn convert_ident(name: String, loc: PyLocation) -> Identifier {
|
||||
let token = Token::new(TokenKind::Symbol, add_procedural_mark(name), loc.row(), loc.column() - 1);
|
||||
let name = VarName::new(token);
|
||||
Identifier::new(None, name)
|
||||
}
|
||||
|
||||
fn convert_param_pattern(arg: String, loc: PyLocation) -> ParamPattern {
|
||||
let token = Token::new(TokenKind::Symbol, arg, loc.row(), loc.column() - 1);
|
||||
let name = VarName::new(token);
|
||||
ParamPattern::VarName(name)
|
||||
}
|
||||
|
||||
fn convert_nd_param(param: Parameter) -> NonDefaultParamSignature {
|
||||
let pat = convert_param_pattern(param.arg, param.location);
|
||||
let t_spec = param.annotation
|
||||
.map(|anot| convert_type_spec(*anot))
|
||||
.map(|t_spec| TypeSpecWithOp::new(COLON, t_spec));
|
||||
NonDefaultParamSignature::new(pat, t_spec)
|
||||
}
|
||||
|
||||
fn _convert_default_param(_param: Parameter) -> DefaultParamSignature {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// TODO: defaults
|
||||
fn convert_params(args: Box<Parameters>) -> Params {
|
||||
let non_defaults = args.args.into_iter().map(convert_nd_param).collect();
|
||||
// let defaults = args. args.defaults.into_iter().map(convert_default_param).collect();
|
||||
Params::new(non_defaults, None, vec![], None)
|
||||
}
|
||||
|
||||
fn convert_for_param(name: String, loc: PyLocation) -> NonDefaultParamSignature {
|
||||
let pat = convert_param_pattern(name, loc);
|
||||
let t_spec = None;
|
||||
NonDefaultParamSignature::new(pat, t_spec)
|
||||
}
|
||||
|
||||
fn convert_for_body(lhs: Located<ExpressionType>, body: Suite) -> Lambda {
|
||||
let ExpressionType::Identifier { name } = lhs.node else { todo!() };
|
||||
let param = convert_for_param(name, lhs.location);
|
||||
let params = Params::new(vec![param], None, vec![], None);
|
||||
let body = body.into_iter().map(convert_statement).collect::<Vec<_>>();
|
||||
let sig = LambdaSignature::new(params, None, TypeBoundSpecs::empty());
|
||||
let op = Token::from_str(TokenKind::ProcArrow, "=>");
|
||||
Lambda::new(sig, op, Block::new(body), DefId(0))
|
||||
}
|
||||
|
||||
fn convert_type_spec(expr: Located<ExpressionType>) -> TypeSpec {
|
||||
match expr.node {
|
||||
ExpressionType::Identifier { name } =>
|
||||
TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple(SimpleTypeSpec::new(convert_ident(name, expr.location), ConstArgs::empty()))),
|
||||
_other => TypeSpec::Infer(Token::new(TokenKind::UBar, "_", expr.location.row(), expr.location.column() - 1)),
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_enclosure_tokens<'i, Elems>(l_kind: TokenKind, elems: Elems, expr_loc: PyLocation) -> (Token, Token)
|
||||
where Elems: Iterator<Item=&'i Located<ExpressionType>> + ExactSizeIterator {
|
||||
let (l_cont, r_cont, r_kind) = match l_kind {
|
||||
TokenKind::LBrace => ("{", "}", TokenKind::RBrace),
|
||||
TokenKind::LParen => ("(", ")", TokenKind::RParen),
|
||||
TokenKind::LSqBr => ("[", "]", TokenKind::RSqBr),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let (l_end, c_end) = if elems.len() == 0 {
|
||||
(expr_loc.row(), expr_loc.column() - 1)
|
||||
} else {
|
||||
let last = elems.last().unwrap();
|
||||
(last.location.row(), last.location.column())
|
||||
};
|
||||
let l_brace = Token::new(l_kind, l_cont, expr_loc.row(), expr_loc.column() - 1);
|
||||
let r_brace = Token::new(r_kind, r_cont, l_end, c_end);
|
||||
(l_brace, r_brace)
|
||||
}
|
||||
|
||||
fn convert_expr(expr: Located<ExpressionType>) -> Expr {
|
||||
match expr.node {
|
||||
ExpressionType::Number { value } => {
|
||||
let (kind, cont) = match value {
|
||||
Number::Integer { value } => (TokenKind::IntLit, value.to_string()),
|
||||
Number::Float { value } => (TokenKind::RatioLit, value.to_string()),
|
||||
Number::Complex { .. } => { return Expr::Dummy(Dummy::new(vec![])); },
|
||||
};
|
||||
let token = Token::new(kind, cont, expr.location.row(), expr.location.column() - 1);
|
||||
Expr::Lit(Literal::new(token))
|
||||
}
|
||||
ExpressionType::String { value } => {
|
||||
let StringGroup::Constant{ value } = value else {
|
||||
return Expr::Dummy(Dummy::new(vec![]));
|
||||
};
|
||||
let value = format!("\"{value}\"");
|
||||
// column - 2 because of the quotes
|
||||
let token = Token::new(TokenKind::StrLit, value, expr.location.row(), expr.location.column() - 2);
|
||||
Expr::Lit(Literal::new(token))
|
||||
}
|
||||
ExpressionType::Call { function, args, keywords: _ } => {
|
||||
let function = convert_expr(*function);
|
||||
let pos_args = args.into_iter().map(|ex| PosArg::new(convert_expr(ex))).collect::<Vec<_>>();
|
||||
let args = Args::new(pos_args, vec![], None);
|
||||
function.call_expr(args)
|
||||
}
|
||||
ExpressionType::Binop { a, op, b } => {
|
||||
let lhs = convert_expr(*a);
|
||||
let rhs = convert_expr(*b);
|
||||
let (kind, cont) = match op {
|
||||
Operator::Add => (TokenKind::Plus, "+"),
|
||||
Operator::Sub => (TokenKind::Minus, "-"),
|
||||
Operator::Mult => (TokenKind::Star, "*"),
|
||||
Operator::Div => (TokenKind::Slash, "/"),
|
||||
Operator::Mod => (TokenKind::Mod, "%"),
|
||||
Operator::Pow => (TokenKind::Pow, "**"),
|
||||
Operator::LShift => (TokenKind::Shl, "<<"),
|
||||
Operator::RShift => (TokenKind::Shr, ">>"),
|
||||
Operator::BitOr => (TokenKind::BitOr, "|"),
|
||||
Operator::BitXor => (TokenKind::BitXor, "^"),
|
||||
Operator::BitAnd => (TokenKind::BitAnd, "&"),
|
||||
Operator::FloorDiv => (TokenKind::FloorDiv, "//"),
|
||||
Operator::MatMult => (TokenKind::AtSign, "@"),
|
||||
};
|
||||
let op = Token::from_str(kind, cont);
|
||||
Expr::BinOp(BinOp::new(op, lhs, rhs))
|
||||
}
|
||||
ExpressionType::Unop { op, a } => {
|
||||
let rhs = convert_expr(*a);
|
||||
let (kind, cont) = match op {
|
||||
UnaryOperator::Pos => (TokenKind::PrePlus, "+"),
|
||||
// UnaryOperator::Not => (TokenKind::PreBitNot, "not"),
|
||||
UnaryOperator::Neg => (TokenKind::PreMinus, "-"),
|
||||
UnaryOperator::Inv => (TokenKind::Minus, "~"),
|
||||
_ => { return Expr::Dummy(Dummy::new(vec![rhs])) }
|
||||
};
|
||||
let op = Token::from_str(kind, cont);
|
||||
Expr::UnaryOp(UnaryOp::new(op, rhs))
|
||||
}
|
||||
// TODO
|
||||
ExpressionType::BoolOp { op, mut values } => {
|
||||
let lhs = convert_expr(values.remove(0));
|
||||
let rhs = convert_expr(values.remove(0));
|
||||
let (kind, cont) = match op {
|
||||
BooleanOperator::And => (TokenKind::AndOp, "and"),
|
||||
BooleanOperator::Or => (TokenKind::OrOp, "or"),
|
||||
};
|
||||
let op = Token::from_str(kind, cont);
|
||||
Expr::BinOp(BinOp::new(op, lhs, rhs))
|
||||
}
|
||||
ExpressionType::Identifier { name } => {
|
||||
let ident = convert_ident(name, expr.location);
|
||||
Expr::Accessor(Accessor::Ident(ident))
|
||||
}
|
||||
ExpressionType::Lambda { args, body } => {
|
||||
let params = convert_params(args);
|
||||
let body = vec![convert_expr(*body)];
|
||||
let sig = LambdaSignature::new(params, None, TypeBoundSpecs::empty());
|
||||
let op = Token::from_str(TokenKind::ProcArrow, "=>");
|
||||
Expr::Lambda(Lambda::new(sig, op, Block::new(body), DefId(0)))
|
||||
}
|
||||
ExpressionType::List { elements } => {
|
||||
let (l_sqbr, r_sqbr) = gen_enclosure_tokens(TokenKind::LSqBr, elements.iter(), expr.location);
|
||||
let elements = elements.into_iter()
|
||||
.map(|ex| PosArg::new(convert_expr(ex)))
|
||||
.collect::<Vec<_>>();
|
||||
let elems = Args::new(elements, vec![], None);
|
||||
Expr::Array(Array::Normal(NormalArray::new(l_sqbr, r_sqbr, elems)))
|
||||
}
|
||||
ExpressionType::Set { elements } => {
|
||||
let (l_brace, r_brace) = gen_enclosure_tokens(TokenKind::LBrace, elements.iter(), expr.location);
|
||||
let elements = elements.into_iter()
|
||||
.map(|ex| PosArg::new(convert_expr(ex)))
|
||||
.collect::<Vec<_>>();
|
||||
let elems = Args::new(elements, vec![], None);
|
||||
Expr::Set(Set::Normal(NormalSet::new(l_brace, r_brace, elems)))
|
||||
}
|
||||
ExpressionType::Dict { elements } => {
|
||||
let (l_brace, r_brace) = gen_enclosure_tokens(TokenKind::LBrace, elements.iter().map(|(_, v)| v), expr.location);
|
||||
let kvs = elements.into_iter()
|
||||
.map(|(k, v)|
|
||||
KeyValue::new(k.map(convert_expr).unwrap_or(Expr::Dummy(Dummy::empty())), convert_expr(v))
|
||||
).collect::<Vec<_>>();
|
||||
Expr::Dict(Dict::Normal(NormalDict::new(l_brace, r_brace, kvs)))
|
||||
}
|
||||
ExpressionType::Tuple { elements } => {
|
||||
let elements = elements.into_iter()
|
||||
.map(|ex| PosArg::new(convert_expr(ex)))
|
||||
.collect::<Vec<_>>();
|
||||
let elems = Args::new(elements, vec![], None);
|
||||
Expr::Tuple(Tuple::Normal(NormalTuple::new(elems)))
|
||||
}
|
||||
ExpressionType::Subscript { a, b } => {
|
||||
let obj = convert_expr(*a);
|
||||
let method = obj.attr_expr(convert_attr("__getitem__".to_string(), expr.location));
|
||||
let args = Args::new(vec![PosArg::new(convert_expr(*b))], vec![], None);
|
||||
method.call_expr(args)
|
||||
}
|
||||
_other => {
|
||||
erg_common::log!(err "unimplemented: {:?}", _other);
|
||||
Expr::Dummy(Dummy::empty())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_block(block: Vec<Located<StatementType>>) -> Block {
|
||||
Block::new(block.into_iter().map(convert_statement).collect::<Vec<_>>())
|
||||
}
|
||||
|
||||
fn convert_statement(stmt: Located<StatementType>) -> Expr {
|
||||
match stmt.node {
|
||||
StatementType::Expression { expression } => convert_expr(expression),
|
||||
StatementType::Assign { mut targets, value } => {
|
||||
let lhs = targets.remove(0);
|
||||
match lhs.node {
|
||||
ExpressionType::Identifier { name } => {
|
||||
let ident = convert_ident(name, stmt.location);
|
||||
let sig = Signature::Var(VarSignature::new(VarPattern::Ident(ident), None));
|
||||
let block = Block::new(vec![convert_expr(value)]);
|
||||
let body = DefBody::new(EQUAL, block, DefId(0));
|
||||
let def = Def::new(sig, body);
|
||||
Expr::Def(def)
|
||||
}
|
||||
ExpressionType::Attribute { value: attr, name } => {
|
||||
let attr = convert_expr(*attr).attr(convert_ident(name, lhs.location));
|
||||
let expr = convert_expr(value);
|
||||
let adef = AttrDef::new(attr, expr);
|
||||
Expr::AttrDef(adef)
|
||||
}
|
||||
_other => Expr::Dummy(Dummy::empty()),
|
||||
}
|
||||
}
|
||||
StatementType::FunctionDef {
|
||||
is_async: _,
|
||||
name,
|
||||
args,
|
||||
body,
|
||||
decorator_list,
|
||||
returns
|
||||
} => {
|
||||
let decos = decorator_list.into_iter().map(|ex| Decorator(convert_expr(ex))).collect::<HashSet<_>>();
|
||||
let ident = convert_ident(name, stmt.location);
|
||||
let params = convert_params(args);
|
||||
let return_t = returns.map(convert_type_spec);
|
||||
let sig = Signature::Subr(SubrSignature::new(decos, ident, TypeBoundSpecs::empty(), params, return_t));
|
||||
let block = convert_block(body);
|
||||
let body = DefBody::new(EQUAL, block, DefId(0));
|
||||
let def = Def::new(sig, body);
|
||||
Expr::Def(def)
|
||||
}
|
||||
// TODO
|
||||
StatementType::ClassDef { name: _, body, bases, keywords: _, decorator_list } => {
|
||||
let exprs = decorator_list.into_iter().map(convert_expr).collect::<Vec<_>>();
|
||||
let bases = bases.into_iter().map(convert_expr).collect::<Vec<_>>();
|
||||
// let decos = decorator_list.into_iter().map(|ex| Decorator(convert_expr(ex))).collect::<Set<_>>();
|
||||
// let ident = convert_ident(name, stmt.location);
|
||||
// let params = Params::new(vec![], None, vec![], None);
|
||||
let mut block = convert_block(body);
|
||||
block.extend(exprs);
|
||||
block.extend(bases);
|
||||
// let body = DefBody::new(EQUAL, block, DefId(0));
|
||||
// let def = Def::new(sig, body);
|
||||
Expr::Dummy(Dummy::new(block.into_iter().collect()))
|
||||
}
|
||||
StatementType::For { is_async: _, target, iter, body, orelse: _ } => {
|
||||
let block = convert_for_body(*target, body);
|
||||
let iter = convert_expr(*iter);
|
||||
let for_ident = convert_ident("for!".to_string(), stmt.location);
|
||||
let for_acc = Expr::Accessor(Accessor::Ident(for_ident));
|
||||
for_acc.call_expr(Args::new(vec![PosArg::new(iter), PosArg::new(Expr::Lambda(block))], vec![], None))
|
||||
}
|
||||
StatementType::While { test, body, orelse: _ } => {
|
||||
let block = convert_block(body);
|
||||
let params = Params::new(vec![], None, vec![], None);
|
||||
let body = Lambda::new(LambdaSignature::new(params, None, TypeBoundSpecs::empty()), Token::DUMMY, block, DefId(0));
|
||||
let test = convert_expr(test);
|
||||
let while_ident = convert_ident("while!".to_string(), stmt.location);
|
||||
let while_acc = Expr::Accessor(Accessor::Ident(while_ident));
|
||||
while_acc.call_expr(Args::new(vec![PosArg::new(test), PosArg::new(Expr::Lambda(body))], vec![], None))
|
||||
}
|
||||
StatementType::If { test, body, orelse } => {
|
||||
let block = convert_block(body);
|
||||
let params = Params::new(vec![], None, vec![], None);
|
||||
let sig = LambdaSignature::new(params.clone(), None, TypeBoundSpecs::empty());
|
||||
let body = Lambda::new(sig, Token::DUMMY, block, DefId(0));
|
||||
let test = convert_expr(test);
|
||||
let if_ident = convert_ident("if!".to_string(), stmt.location);
|
||||
let if_acc = Expr::Accessor(Accessor::Ident(if_ident));
|
||||
if let Some(orelse) = orelse {
|
||||
let else_block = convert_block(orelse);
|
||||
let sig = LambdaSignature::new(params, None, TypeBoundSpecs::empty());
|
||||
let else_body = Lambda::new(sig, Token::DUMMY, else_block, DefId(0));
|
||||
let args = Args::new(vec![PosArg::new(test), PosArg::new(Expr::Lambda(body)), PosArg::new(Expr::Lambda(else_body))], vec![], None);
|
||||
if_acc.call_expr(args)
|
||||
} else {
|
||||
let args = Args::new(vec![PosArg::new(test), PosArg::new(Expr::Lambda(body))], vec![], None);
|
||||
if_acc.call_expr(args)
|
||||
}
|
||||
}
|
||||
// This is fine for static analysis only.
|
||||
StatementType::Return { value } => {
|
||||
value.map(convert_expr)
|
||||
.unwrap_or_else(||Expr::Tuple(Tuple::Normal(NormalTuple::new(Args::empty()))))
|
||||
}
|
||||
_other => {
|
||||
erg_common::log!(err "unimplemented: {:?}", _other);
|
||||
Expr::Dummy(Dummy::empty())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn convert_program(program: Program) -> Module {
|
||||
Module::new(program.statements.into_iter().map(convert_statement).collect())
|
||||
}
|
2
crates/py2erg/lib.rs
Normal file
2
crates/py2erg/lib.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
mod convert;
|
||||
pub use convert::*;
|
3
extension/.gitignore
vendored
Normal file
3
extension/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*.vsix
|
||||
node_modules
|
||||
example.py
|
17
extension/.vscode/launch.json
vendored
Normal file
17
extension/.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// A launch configuration that launches the extension inside a new window
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
3
extension/.vscodeignore
Normal file
3
extension/.vscodeignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
.vscode/**
|
||||
.vscode-test/**
|
||||
.gitignore
|
19
extension/LICENSE
Normal file
19
extension/LICENSE
Normal file
|
@ -0,0 +1,19 @@
|
|||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
11
extension/README.md
Normal file
11
extension/README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# vscode-pype
|
||||
|
||||
## Requirements
|
||||
|
||||
You need to have the [pype](https://github.com/mtshiba/pype) installed on your system.
|
||||
|
||||
To install it, run the following command:
|
||||
|
||||
```console
|
||||
cargo install pype
|
||||
```
|
32
extension/extension.js
Normal file
32
extension/extension.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
"use strict";
|
||||
const vscode = require("vscode");
|
||||
const languageclient = require("vscode-languageclient");
|
||||
|
||||
let client;
|
||||
|
||||
function activate(context) {
|
||||
try {
|
||||
const serverOptions = {
|
||||
command: "pype",
|
||||
args: ["--server"]
|
||||
};
|
||||
const clientOptions = {
|
||||
documentSelector: [
|
||||
{
|
||||
scheme: "file",
|
||||
language: "python",
|
||||
}
|
||||
],
|
||||
};
|
||||
client = new languageclient.LanguageClient("pype", serverOptions, clientOptions);
|
||||
context.subscriptions.push(client.start());
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage("failed to start pype.");
|
||||
}
|
||||
}
|
||||
|
||||
function deactivate() {
|
||||
if (client) return client.stop();
|
||||
}
|
||||
|
||||
module.exports = { activate, deactivate }
|
113
extension/package-lock.json
generated
Normal file
113
extension/package-lock.json
generated
Normal file
|
@ -0,0 +1,113 @@
|
|||
{
|
||||
"name": "vscode-pype",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "vscode-pype",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"vscode-languageclient": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.70.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.3.7",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
|
||||
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-jsonrpc": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
|
||||
"integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==",
|
||||
"engines": {
|
||||
"node": ">=8.0.0 || >=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageclient": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
|
||||
"integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
|
||||
"dependencies": {
|
||||
"minimatch": "^3.0.4",
|
||||
"semver": "^7.3.4",
|
||||
"vscode-languageserver-protocol": "3.16.0"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.52.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver-protocol": {
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
|
||||
"integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
|
||||
"dependencies": {
|
||||
"vscode-jsonrpc": "6.0.0",
|
||||
"vscode-languageserver-types": "3.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver-types": {
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
|
||||
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
}
|
||||
}
|
||||
}
|
38
extension/package.json
Normal file
38
extension/package.json
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "vscode-pype",
|
||||
"displayName": "pype",
|
||||
"description": "A Python static code analyzer & language server for VSCode",
|
||||
"publisher": "gmshiba",
|
||||
"version": "0.1.0",
|
||||
"engines": {
|
||||
"vscode": "^1.70.0"
|
||||
},
|
||||
"categories": [
|
||||
"Programming Languages"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mtshiba/pype.git"
|
||||
},
|
||||
"main": "./extension.js",
|
||||
"activationEvents": [
|
||||
"onLanguage:python"
|
||||
],
|
||||
"contributes": {
|
||||
"languages": [
|
||||
{
|
||||
"id": "python",
|
||||
"aliases": [
|
||||
"Python",
|
||||
"python"
|
||||
],
|
||||
"extensions": [
|
||||
".py"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageclient": "^7.0.0"
|
||||
}
|
||||
}
|
105
src/analyze.rs
Normal file
105
src/analyze.rs
Normal file
|
@ -0,0 +1,105 @@
|
|||
use erg_common::traits::{Runnable, Stream};
|
||||
use erg_common::config::{ErgConfig};
|
||||
use erg_common::error::MultiErrorDisplay;
|
||||
use erg_compiler::artifact::{BuildRunnable, CompleteArtifact, IncompleteArtifact, Buildable};
|
||||
use erg_compiler::context::Context;
|
||||
use erg_compiler::erg_parser::ast::AST;
|
||||
use erg_compiler::error::{CompileErrors, CompileError};
|
||||
use erg_compiler::lower::ASTLowerer;
|
||||
use rustpython_parser::parser;
|
||||
|
||||
use crate::handle_err;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct PythonAnalyzer {
|
||||
pub cfg: ErgConfig,
|
||||
checker: ASTLowerer,
|
||||
}
|
||||
|
||||
impl Runnable for PythonAnalyzer {
|
||||
type Err = CompileError;
|
||||
type Errs = CompileErrors;
|
||||
const NAME: &'static str = "Python Analyzer";
|
||||
fn new(cfg: ErgConfig) -> Self {
|
||||
let checker = ASTLowerer::new(cfg.clone());
|
||||
Self {
|
||||
checker,
|
||||
cfg,
|
||||
}
|
||||
}
|
||||
fn cfg(&self) -> &ErgConfig {
|
||||
&self.cfg
|
||||
}
|
||||
fn finish(&mut self) {
|
||||
self.checker.finish();
|
||||
}
|
||||
fn initialize(&mut self) {
|
||||
self.checker.initialize();
|
||||
}
|
||||
fn clear(&mut self) {
|
||||
self.checker.clear();
|
||||
}
|
||||
fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
|
||||
self.checker.eval(src)
|
||||
}
|
||||
fn exec(&mut self) -> Result<i32, Self::Errs> {
|
||||
self.checker.exec()
|
||||
}
|
||||
}
|
||||
|
||||
impl Buildable for PythonAnalyzer {
|
||||
fn build(&mut self, code: String, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
|
||||
self.analyze(code, mode)
|
||||
}
|
||||
fn pop_context(&mut self) -> Option<Context> {
|
||||
Some(self.checker.pop_mod_ctx())
|
||||
}
|
||||
fn get_context(&self) -> Option<&Context> {
|
||||
Some(self.checker.get_mod_ctx())
|
||||
}
|
||||
}
|
||||
|
||||
impl BuildRunnable for PythonAnalyzer {}
|
||||
|
||||
impl PythonAnalyzer {
|
||||
pub fn analyze(&mut self, py_code: String, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
|
||||
let filename = self.cfg.input.filename();
|
||||
let py_program = parser::parse_program(&py_code).unwrap();
|
||||
let erg_module = py2erg::convert_program(py_program);
|
||||
let erg_ast = AST::new(erg_common::Str::rc(filename), erg_module);
|
||||
self.checker.lower(erg_ast, mode).map_err(|iart| {
|
||||
let filtered = handle_err::filter_errors(self.checker.get_mod_ctx(), iart.errors);
|
||||
IncompleteArtifact::new(iart.object, filtered, iart.warns)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
let filename = self.cfg.input.filename();
|
||||
let py_code = self.cfg.input.read();
|
||||
println!("Start checking: {filename}");
|
||||
match self.analyze(py_code, "exec") {
|
||||
Ok(artifact) => {
|
||||
if !artifact.warns.is_empty() {
|
||||
println!("Found warnings: {}", artifact.warns.len());
|
||||
artifact.warns.fmt_all_stderr();
|
||||
}
|
||||
println!("All checks OK.");
|
||||
std::process::exit(0);
|
||||
}
|
||||
Err(artifact) => {
|
||||
if !artifact.warns.is_empty() {
|
||||
println!("Found warnings: {}", artifact.warns.len());
|
||||
artifact.warns.fmt_all_stderr();
|
||||
}
|
||||
if artifact.errors.is_empty() {
|
||||
println!("All checks OK.");
|
||||
std::process::exit(0);
|
||||
} else {
|
||||
println!("Found errors: {}", artifact.errors.len());
|
||||
artifact.errors.fmt_all_stderr();
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
src/handle_err.rs
Normal file
40
src/handle_err.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use erg_common::error::ErrorKind;
|
||||
use erg_common::style::{remove_style, StyledString, Color};
|
||||
use erg_compiler::error::{CompileErrors, CompileError};
|
||||
use erg_compiler::context::Context;
|
||||
|
||||
pub(crate) fn filter_errors(ctx: &Context, errors: CompileErrors) -> CompileErrors {
|
||||
errors.into_iter().filter_map(|error| filter_error(ctx, error)).collect()
|
||||
}
|
||||
|
||||
fn filter_error(ctx: &Context, error: CompileError) -> Option<CompileError> {
|
||||
match error.core.kind {
|
||||
ErrorKind::VisibilityError => None,
|
||||
ErrorKind::NameError => Some(map_name_error(ctx, error)),
|
||||
ErrorKind::AssignError => handle_assign_error(error),
|
||||
_ => Some(error),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_name_error(ctx: &Context, mut error: CompileError) -> CompileError {
|
||||
let hint = error.core.sub_messages.iter_mut().find_map(|sub| sub.hint.as_mut());
|
||||
if let Some(hint) = hint {
|
||||
if let Some(name) = hint.split("exists a similar name variable: ").last() {
|
||||
let name = remove_style(name);
|
||||
if let Some((_, vi)) = ctx.get_var_info(&name) {
|
||||
if let Some(py_name) = &vi.py_name {
|
||||
*hint = format!("exists a similar name variable: {}", StyledString::new(&py_name[..], Some(Color::Green), None));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
error
|
||||
}
|
||||
|
||||
fn handle_assign_error(error: CompileError) -> Option<CompileError> {
|
||||
if error.core.main_message.ends_with("cannot be assigned more than once") {
|
||||
None
|
||||
} else {
|
||||
Some(error)
|
||||
}
|
||||
}
|
82
src/main.rs
Normal file
82
src/main.rs
Normal file
|
@ -0,0 +1,82 @@
|
|||
mod handle_err;
|
||||
mod analyze;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use analyze::PythonAnalyzer;
|
||||
use els::Server;
|
||||
use erg_common::config::{Input, ErgConfig};
|
||||
use erg_common::traits::Runnable;
|
||||
|
||||
pub fn parse_args() -> ErgConfig {
|
||||
let mut args = env::args();
|
||||
args.next(); // "pype"
|
||||
let mut cfg = ErgConfig::default();
|
||||
while let Some(arg) = args.next() {
|
||||
match &arg[..] {
|
||||
"--" => {
|
||||
for arg in args {
|
||||
cfg.runtime_args.push(Box::leak(arg.into_boxed_str()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
"-c" | "--code" => {
|
||||
cfg.input = Input::Str(args.next().expect("the value of `-c` is not passed"));
|
||||
}
|
||||
"--server" => {
|
||||
cfg.mode = "server";
|
||||
}
|
||||
"--verbose" => {
|
||||
cfg.verbose = args
|
||||
.next()
|
||||
.expect("the value of `--verbose` is not passed")
|
||||
.parse::<u8>()
|
||||
.expect("the value of `--verbose` is not a number");
|
||||
}
|
||||
"-V" | "--version" => {
|
||||
println!("Erg {}", env!("CARGO_PKG_VERSION"));
|
||||
std::process::exit(0);
|
||||
}
|
||||
other if other.starts_with('-') => {
|
||||
println!(
|
||||
"\
|
||||
invalid option: {other}
|
||||
|
||||
USAGE:
|
||||
pype [OPTIONS] [SUBCOMMAND] [ARGS]...
|
||||
|
||||
For more information try `pype --help`"
|
||||
);
|
||||
std::process::exit(2);
|
||||
}
|
||||
_ => {
|
||||
cfg.input = Input::File(
|
||||
PathBuf::from_str(&arg[..])
|
||||
.unwrap_or_else(|_| panic!("invalid file path: {}", arg)),
|
||||
);
|
||||
if let Some("--") = args.next().as_ref().map(|s| &s[..]) {
|
||||
for arg in args {
|
||||
cfg.runtime_args.push(Box::leak(arg.into_boxed_str()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let cfg = parse_args();
|
||||
if cfg.mode == "server" {
|
||||
let mut lang_server = Server::<PythonAnalyzer>::new();
|
||||
lang_server.run().unwrap_or_else(|_| {
|
||||
std::process::exit(1);
|
||||
});
|
||||
} else {
|
||||
let mut analyzer = PythonAnalyzer::new(cfg);
|
||||
analyzer.run();
|
||||
}
|
||||
}
|
28
tests/test.py
Normal file
28
tests/test.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
def add(x, y):
|
||||
return x + y
|
||||
|
||||
print(add(1, 2))
|
||||
print(add(1, "a"))
|
||||
add.x = 1
|
||||
|
||||
def add2(x: int, y: int) -> str:
|
||||
return x + y
|
||||
|
||||
print(add2(1, 2))
|
||||
|
||||
for i in [1, 2, 3]:
|
||||
j = i + "aa"
|
||||
print(j)
|
||||
|
||||
while "aaa":
|
||||
print("invalid")
|
||||
break
|
||||
|
||||
class C:
|
||||
x = 1 + "a"
|
||||
|
||||
dic = {"a": 1, "b": 2}
|
||||
print(dic["c"])
|
||||
|
||||
a = [1, 2, 3]
|
||||
print(a[4])
|
Loading…
Add table
Add a link
Reference in a new issue