diff --git a/.all-contributorsrc b/.all-contributorsrc
new file mode 100644
index 00000000..3ee65ba1
--- /dev/null
+++ b/.all-contributorsrc
@@ -0,0 +1,25 @@
+{
+ "projectName": "cairo-lint",
+ "projectOwner": "keep-starknet-strange",
+ "repoType": "github",
+ "repoHost": "https://github.com",
+ "files": [
+ "README.md"
+ ],
+ "imageSize": 100,
+ "commit": true,
+ "commitConvention": "angular",
+ "contributors": [
+ {
+ "login": "0xLucqs",
+ "name": "0xLucqs",
+ "avatar_url": "https://avatars.githubusercontent.com/u/70894690?v=4",
+ "profile": "https://github.com/0xLucqs",
+ "contributions": [
+ "code"
+ ]
+ }
+ ],
+ "contributorsPerLine": 7,
+ "linkToUsage": false
+}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..6de8ec16
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,27 @@
+on: [push, pull_request]
+
+name: Test
+
+jobs:
+ test:
+ name: Test
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Get corelib
+ run: git clone -b lucas/multiline_diag https://github.com/0xLucqs/cairo
+
+ - name: Install toolchain
+ run: rustup show
+
+ - uses: Swatinem/rust-cache@v2
+
+ - name: Run cargo clippy
+ run: cargo clippy -- -D warnings
+
+ - name: Run cargo test
+ run: CORELIB_PATH="$(pwd)/cairo/corelib/src" cargo test
+
+ - name: Run cargo fmt
+ run: rustup toolchain install nightly && rustup component add --toolchain nightly-x86_64-unknown-linux-gnu rustfmt && cargo +nightly fmt -- --check
diff --git a/.gitignore b/.gitignore
index eb5a316c..54088d57 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
target
+.DS_Store
diff --git a/Cargo.lock b/Cargo.lock
index b0d23f72..e3d46352 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -187,6 +187,7 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
[[package]]
name = "cairo-lang-casm"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-utils",
"indoc",
@@ -199,6 +200,7 @@ dependencies = [
[[package]]
name = "cairo-lang-compiler"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"anyhow",
"cairo-lang-defs",
@@ -222,6 +224,7 @@ dependencies = [
[[package]]
name = "cairo-lang-debug"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-utils",
]
@@ -229,6 +232,7 @@ dependencies = [
[[package]]
name = "cairo-lang-defs"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-debug",
"cairo-lang-diagnostics",
@@ -244,6 +248,7 @@ dependencies = [
[[package]]
name = "cairo-lang-diagnostics"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-debug",
"cairo-lang-filesystem",
@@ -254,6 +259,7 @@ dependencies = [
[[package]]
name = "cairo-lang-doc"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-defs",
"cairo-lang-formatter",
@@ -267,6 +273,7 @@ dependencies = [
[[package]]
name = "cairo-lang-eq-solver"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-utils",
"good_lp",
@@ -275,6 +282,7 @@ dependencies = [
[[package]]
name = "cairo-lang-filesystem"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-debug",
"cairo-lang-utils",
@@ -287,6 +295,7 @@ dependencies = [
[[package]]
name = "cairo-lang-formatter"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"anyhow",
"cairo-lang-diagnostics",
@@ -306,6 +315,7 @@ dependencies = [
[[package]]
name = "cairo-lang-language-server"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"anyhow",
"cairo-lang-compiler",
@@ -340,6 +350,7 @@ dependencies = [
[[package]]
name = "cairo-lang-lowering"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-debug",
"cairo-lang-defs",
@@ -362,6 +373,7 @@ dependencies = [
[[package]]
name = "cairo-lang-parser"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-diagnostics",
"cairo-lang-filesystem",
@@ -380,6 +392,7 @@ dependencies = [
[[package]]
name = "cairo-lang-plugins"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-defs",
"cairo-lang-diagnostics",
@@ -397,6 +410,7 @@ dependencies = [
[[package]]
name = "cairo-lang-proc-macros"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-debug",
"quote",
@@ -406,6 +420,7 @@ dependencies = [
[[package]]
name = "cairo-lang-project"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-filesystem",
"cairo-lang-utils",
@@ -418,6 +433,7 @@ dependencies = [
[[package]]
name = "cairo-lang-semantic"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-debug",
"cairo-lang-defs",
@@ -442,6 +458,7 @@ dependencies = [
[[package]]
name = "cairo-lang-sierra"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"anyhow",
"cairo-lang-utils",
@@ -467,6 +484,7 @@ dependencies = [
[[package]]
name = "cairo-lang-sierra-ap-change"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-eq-solver",
"cairo-lang-sierra",
@@ -481,6 +499,7 @@ dependencies = [
[[package]]
name = "cairo-lang-sierra-gas"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-eq-solver",
"cairo-lang-sierra",
@@ -495,6 +514,7 @@ dependencies = [
[[package]]
name = "cairo-lang-sierra-generator"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-debug",
"cairo-lang-defs",
@@ -517,6 +537,7 @@ dependencies = [
[[package]]
name = "cairo-lang-sierra-to-casm"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"assert_matches",
"cairo-lang-casm",
@@ -536,6 +557,7 @@ dependencies = [
[[package]]
name = "cairo-lang-sierra-type-size"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-sierra",
"cairo-lang-utils",
@@ -544,6 +566,7 @@ dependencies = [
[[package]]
name = "cairo-lang-starknet"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"anyhow",
"cairo-lang-compiler",
@@ -572,6 +595,7 @@ dependencies = [
[[package]]
name = "cairo-lang-starknet-classes"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-casm",
"cairo-lang-sierra",
@@ -593,6 +617,7 @@ dependencies = [
[[package]]
name = "cairo-lang-syntax"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-debug",
"cairo-lang-filesystem",
@@ -607,6 +632,7 @@ dependencies = [
[[package]]
name = "cairo-lang-syntax-codegen"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"genco",
"xshell",
@@ -615,6 +641,7 @@ dependencies = [
[[package]]
name = "cairo-lang-test-plugin"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"anyhow",
"cairo-lang-compiler",
@@ -640,6 +667,7 @@ dependencies = [
[[package]]
name = "cairo-lang-test-utils"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"cairo-lang-formatter",
"cairo-lang-utils",
@@ -651,6 +679,7 @@ dependencies = [
[[package]]
name = "cairo-lang-utils"
version = "2.7.0"
+source = "git+https://github.com/0xLucqs/cairo?branch=lucas/multiline_diag#11f8a1979834e39f4a79cc9d3a2707017b46e1fa"
dependencies = [
"hashbrown 0.14.5",
"indexmap 2.3.0",
@@ -661,6 +690,63 @@ dependencies = [
"serde",
]
+[[package]]
+name = "cairo-lint"
+version = "0.1.0"
+dependencies = [
+ "cairo-lang-compiler",
+ "cairo-lang-defs",
+ "cairo-lang-diagnostics",
+ "cairo-lang-filesystem",
+ "cairo-lang-language-server",
+ "cairo-lang-lowering",
+ "cairo-lang-parser",
+ "cairo-lang-semantic",
+ "cairo-lang-syntax",
+ "cairo-lang-test-plugin",
+ "cairo-lang-utils",
+ "salsa",
+]
+
+[[package]]
+name = "cairo-lint-core"
+version = "0.1.0"
+dependencies = [
+ "cairo-lang-compiler",
+ "cairo-lang-defs",
+ "cairo-lang-diagnostics",
+ "cairo-lang-filesystem",
+ "cairo-lang-language-server",
+ "cairo-lang-lowering",
+ "cairo-lang-parser",
+ "cairo-lang-semantic",
+ "cairo-lang-syntax",
+ "cairo-lang-test-plugin",
+ "cairo-lang-test-utils",
+ "cairo-lang-utils",
+ "cairo-lint-test-utils",
+ "ctor",
+ "indoc",
+ "paste",
+ "pretty_assertions",
+ "salsa",
+ "test-case",
+]
+
+[[package]]
+name = "cairo-lint-test-utils"
+version = "0.1.0"
+dependencies = [
+ "cairo-lang-defs",
+ "cairo-lang-diagnostics",
+ "cairo-lang-filesystem",
+ "cairo-lang-semantic",
+ "cairo-lang-test-utils",
+ "cairo-lang-utils",
+ "cairo-lint-core",
+ "paste",
+]
+
[[package]]
name = "camino"
version = "1.1.7"
@@ -777,6 +863,16 @@ dependencies = [
"typenum",
]
+[[package]]
+name = "ctor"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
+dependencies = [
+ "quote",
+ "syn 2.0.72",
+]
+
[[package]]
name = "dashmap"
version = "5.5.3"
@@ -1544,6 +1640,12 @@ dependencies = [
"windows-targets 0.52.6",
]
+[[package]]
+name = "paste"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+
[[package]]
name = "path-clean"
version = "1.0.1"
@@ -2456,46 +2558,6 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
-[[package]]
-name = "unretardify"
-version = "0.1.0"
-dependencies = [
- "cairo-lang-compiler",
- "cairo-lang-defs",
- "cairo-lang-diagnostics",
- "cairo-lang-filesystem",
- "cairo-lang-language-server",
- "cairo-lang-lowering",
- "cairo-lang-parser",
- "cairo-lang-semantic",
- "cairo-lang-syntax",
- "cairo-lang-test-plugin",
- "cairo-lang-utils",
- "salsa",
-]
-
-[[package]]
-name = "unretardify-core"
-version = "0.1.0"
-dependencies = [
- "cairo-lang-compiler",
- "cairo-lang-defs",
- "cairo-lang-diagnostics",
- "cairo-lang-filesystem",
- "cairo-lang-language-server",
- "cairo-lang-lowering",
- "cairo-lang-parser",
- "cairo-lang-semantic",
- "cairo-lang-syntax",
- "cairo-lang-test-plugin",
- "cairo-lang-test-utils",
- "cairo-lang-utils",
- "indoc",
- "pretty_assertions",
- "salsa",
- "test-case",
-]
-
[[package]]
name = "url"
version = "2.5.2"
diff --git a/Cargo.toml b/Cargo.toml
index b6bf2cd0..16a57864 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,28 +1,30 @@
[workspace]
resolver = "2"
-members = ["crates/unretardify-cli", "crates/unretardify-core"]
+members = ["crates/cairo-lint-cli", "crates/cairo-lint-core", "crates/cairo-lint-test-utils"]
[workspace.package]
version = "0.1.0"
edition = "2021"
-repository = "https://github.com/keep-starknet-strange/unretardify"
+repository = "https://github.com/keep-starknet-strange/cairo-lint"
license = "Apache-2.0"
license-file = "LICENSE"
[workspace.dependencies]
-cairo-lang-compiler = { path = "../cairo/crates/cairo-lang-compiler" }
-cairo-lang-parser = { path = "../cairo/crates/cairo-lang-parser" }
-cairo-lang-utils = { path = "../cairo/crates/cairo-lang-utils" }
-cairo-lang-semantic = { path = "../cairo/crates/cairo-lang-semantic" }
-cairo-lang-filesystem = { path = "../cairo/crates/cairo-lang-filesystem" }
-cairo-lang-diagnostics = { path = "../cairo/crates/cairo-lang-diagnostics" }
-cairo-lang-test-plugin = { path = "../cairo/crates/cairo-lang-test-plugin" }
-cairo-lang-lowering = { path = "../cairo/crates/cairo-lang-lowering" }
-cairo-lang-syntax = { path = "../cairo/crates/cairo-lang-syntax" }
-cairo-lang-defs = { path = "../cairo/crates/cairo-lang-defs" }
-cairo-lang-test-utils = { path = "../cairo/crates/cairo-lang-test-utils" }
-cairo-lang-language-server = { path = "../cairo/crates/cairo-lang-language-server" }
+cairo-lang-compiler = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-parser = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-utils = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-semantic = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-filesystem = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-diagnostics = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-test-plugin = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-lowering = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-syntax = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-defs = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-test-utils = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
+cairo-lang-language-server = { git = "https://github.com/0xLucqs/cairo", branch = "lucas/multiline_diag" }
salsa = "0.16.1"
indoc = "2"
test-case = "3.0"
pretty_assertions = "1.4.0"
+ctor = "0.2.8"
+paste = "1.0.15"
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..7041a252
--- /dev/null
+++ b/README.md
@@ -0,0 +1,77 @@
+![](./resources/img/logo.jpg)
+
+
+
+ cairo-lint
+
+
+[![Check Workflow Status](https://github.com/keep-starknet-strange/snos/actions/workflows/check.yml/badge.svg)](https://github.com/keep-starknet-strange/snos/actions/workflows/check.yml)
+[![Telegram](https://img.shields.io/badge/telegram-cairo-lint-blue.svg?logo=telegram)](https://t.me/cairo-lint)
+
+[![Exploration_Team](https://img.shields.io/badge/Exploration_Team-29296E.svg?&style=for-the-badge&logo=data:image/svg%2bxml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIGlkPSJhIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxODEgMTgxIj48ZGVmcz48c3R5bGU+LmJ7ZmlsbDojZmZmO308L3N0eWxlPjwvZGVmcz48cGF0aCBjbGFzcz0iYiIgZD0iTTE3Ni43Niw4OC4xOGwtMzYtMzcuNDNjLTEuMzMtMS40OC0zLjQxLTIuMDQtNS4zMS0xLjQybC0xMC42MiwyLjk4LTEyLjk1LDMuNjNoLjc4YzUuMTQtNC41Nyw5LjktOS41NSwxNC4yNS0xNC44OSwxLjY4LTEuNjgsMS44MS0yLjcyLDAtNC4yN0w5Mi40NSwuNzZxLTEuOTQtMS4wNC00LjAxLC4xM2MtMTIuMDQsMTIuNDMtMjMuODMsMjQuNzQtMzYsMzcuNjktMS4yLDEuNDUtMS41LDMuNDQtLjc4LDUuMThsNC4yNywxNi41OGMwLDIuNzIsMS40Miw1LjU3LDIuMDcsOC4yOS00LjczLTUuNjEtOS43NC0xMC45Ny0xNS4wMi0xNi4wNi0xLjY4LTEuODEtMi41OS0xLjgxLTQuNCwwTDQuMzksODguMDVjLTEuNjgsMi4zMy0xLjgxLDIuMzMsMCw0LjUzbDM1Ljg3LDM3LjNjMS4zNiwxLjUzLDMuNSwyLjEsNS40NCwxLjQybDExLjQtMy4xMSwxMi45NS0zLjYzdi45MWMtNS4yOSw0LjE3LTEwLjIyLDguNzYtMTQuNzYsMTMuNzNxLTMuNjMsMi45OC0uNzgsNS4zMWwzMy40MSwzNC44NGMyLjIsMi4yLDIuOTgsMi4yLDUuMTgsMGwzNS40OC0zNy4xN2MxLjU5LTEuMzgsMi4xNi0zLjYsMS40Mi01LjU3LTEuNjgtNi4wOS0zLjI0LTEyLjMtNC43OS0xOC4zOS0uNzQtMi4yNy0xLjIyLTQuNjItMS40Mi02Ljk5LDQuMyw1LjkzLDkuMDcsMTEuNTIsMTQuMjUsMTYuNzEsMS42OCwxLjY4LDIuNzIsMS42OCw0LjQsMGwzNC4zMi0zNS43NHExLjU1LTEuODEsMC00LjAxWm0tNzIuMjYsMTUuMTVjLTMuMTEtLjc4LTYuMDktMS41NS05LjE5LTIuNTktMS43OC0uMzQtMy42MSwuMy00Ljc5LDEuNjhsLTEyLjk1LDEzLjg2Yy0uNzYsLjg1LTEuNDUsMS43Ni0yLjA3LDIuNzJoLS42NWMxLjMtNS4zMSwyLjcyLTEwLjYyLDQuMDEtMTUuOGwxLjY4LTYuNzNjLjg0LTIuMTgsLjE1LTQuNjUtMS42OC02LjA5bC0xMi45NS0xNC4xMmMtLjY0LS40NS0xLjE0LTEuMDgtMS40Mi0xLjgxbDE5LjA0LDUuMTgsMi41OSwuNzhjMi4wNCwuNzYsNC4zMywuMTQsNS43LTEuNTVsMTIuOTUtMTQuMzhzLjc4LTEuMDQsMS42OC0xLjE3Yy0xLjgxLDYuNi0yLjk4LDE0LjEyLTUuNDQsMjAuNDYtMS4wOCwyLjk2LS4wOCw2LjI4LDIuNDYsOC4xNiw0LjI3LDQuMTQsOC4yOSw4LjU1LDEyLjk1LDEyLjk1LDAsMCwxLjMsLjkxLDEuNDIsMi4wN2wtMTMuMzQtMy42M1oiLz48L3N2Zz4=)](https://github.com/keep-starknet-strange)
+
+
+
+
+A collection of lints to catch common mistakes and improve your [Cairo](https://github.com/starkware-libs/cairo) code.
+
+## Usage
+
+cairo-lint can either be used as a library or as a standalone binary. It can either just detect or fix the detected
+problems.
+
+## Contributors
+
+
+
+
+
+
+
+
+
+
+
+## Contributing
+
+**[Join the telegram group](t.me/cairo-lint)**
+
+To run the tests you'll need to provide the path to the cairo corelib (at some point this should be automated but we're
+not there yet).
+
+```sh
+CORELIB_PATH="/path/to/corelibe" cargo test
+```
+
+Each lint should have its own tests and should be extensive. To create a new test for a lint you need to create a file
+in the [test_files folder](./crates/cairo-lint-core/tests/test_files/) and should be named as your lint. The file
+should have this format:
+
+```txt
+//! > Test name
+
+//! > cairo_code
+fn main() {
+ let a: Option = Option::Some(1);
+}
+```
+
+Then in the [test file](crates/cairo-lint-core/tests/tests.rs) declare your lint like so:
+
+```rs
+test_file!(if_let, "Test name");
+```
+
+The first argument is the lint name (also the file name) and the other ones are the test names. After that you can run
+
+```
+FIX_TESTS=1 cargo test -p cairo-lint-core
+```
+
+This will generate the expected values in your test file. Make sure it is correct.
diff --git a/crates/unretardify-cli/Cargo.toml b/crates/cairo-lint-cli/Cargo.toml
similarity index 96%
rename from crates/unretardify-cli/Cargo.toml
rename to crates/cairo-lint-cli/Cargo.toml
index e5618379..b2acb5e4 100644
--- a/crates/unretardify-cli/Cargo.toml
+++ b/crates/cairo-lint-cli/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "unretardify"
+name = "cairo-lint"
version.workspace = true
edition.workspace = true
repository.workspace = true
diff --git a/crates/unretardify-cli/src/main.rs b/crates/cairo-lint-cli/src/main.rs
similarity index 100%
rename from crates/unretardify-cli/src/main.rs
rename to crates/cairo-lint-cli/src/main.rs
diff --git a/crates/unretardify-core/Cargo.toml b/crates/cairo-lint-core/Cargo.toml
similarity index 84%
rename from crates/unretardify-core/Cargo.toml
rename to crates/cairo-lint-core/Cargo.toml
index c4b2542d..e922c2d5 100644
--- a/crates/unretardify-core/Cargo.toml
+++ b/crates/cairo-lint-core/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "unretardify-core"
+name = "cairo-lint-core"
version.workspace = true
edition.workspace = true
repository.workspace = true
@@ -25,3 +25,6 @@ indoc.workspace = true
cairo-lang-test-utils.workspace = true
test-case.workspace = true
pretty_assertions.workspace = true
+ctor.workspace = true
+cairo-lint-test-utils = { path = "../cairo-lint-test-utils" }
+paste.workspace = true
diff --git a/crates/unretardify-core/src/db.rs b/crates/cairo-lint-core/src/db.rs
similarity index 97%
rename from crates/unretardify-core/src/db.rs
rename to crates/cairo-lint-core/src/db.rs
index eff7cb64..b82a8ab0 100644
--- a/crates/unretardify-core/src/db.rs
+++ b/crates/cairo-lint-core/src/db.rs
@@ -11,7 +11,7 @@ use cairo_lang_syntax::node::db::{SyntaxDatabase, SyntaxGroup};
use cairo_lang_test_plugin::test_plugin_suite;
use cairo_lang_utils::Upcast;
-use crate::plugin::unretardify_plugin_suite;
+use crate::plugin::cairo_lint_plugin_suite;
/// The Cairo compiler Salsa database tailored for language server usage.
#[salsa::database(DefsDatabase, FilesDatabase, LoweringDatabase, ParserDatabase, SemanticDatabase, SyntaxDatabase)]
@@ -22,7 +22,7 @@ impl AnalysisDatabase {
pub fn new() -> Self {
let mut db = Self { storage: Default::default() };
- let plugin_suite = [get_default_plugin_suite(), test_plugin_suite(), unretardify_plugin_suite()]
+ let plugin_suite = [get_default_plugin_suite(), test_plugin_suite(), cairo_lint_plugin_suite()]
.into_iter()
.fold(PluginSuite::default(), |mut acc, suite| {
acc.add(suite);
diff --git a/crates/cairo-lint-core/src/fix.rs b/crates/cairo-lint-core/src/fix.rs
new file mode 100644
index 00000000..b3970fab
--- /dev/null
+++ b/crates/cairo-lint-core/src/fix.rs
@@ -0,0 +1,67 @@
+use cairo_lang_defs::plugin::PluginDiagnostic;
+use cairo_lang_filesystem::span::TextSpan;
+use cairo_lang_semantic::diagnostic::SemanticDiagnosticKind;
+use cairo_lang_semantic::SemanticDiagnostic;
+use cairo_lang_syntax::node::ast::{ExprMatch, Pattern};
+use cairo_lang_syntax::node::db::SyntaxGroup;
+use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode};
+use cairo_lang_utils::Upcast;
+
+use crate::db::AnalysisDatabase;
+use crate::plugin::{diagnostic_kind_from_message, RetardationKind};
+
+#[derive(Default)]
+pub struct Fix {
+ pub span: TextSpan,
+ pub suggestion: String,
+}
+
+pub fn fix_semantic_diagnostic(db: &AnalysisDatabase, diag: &SemanticDiagnostic) -> String {
+ match diag.kind {
+ SemanticDiagnosticKind::UnusedVariable => {
+ format!("_{}", diag.stable_location.syntax_node(db.upcast()).get_text(db.upcast()))
+ }
+ SemanticDiagnosticKind::PluginDiagnostic(ref diag) => Fixer.fix_plugin_diagnostic(db, diag),
+ _ => "".to_owned(),
+ }
+}
+
+#[derive(Default)]
+pub struct Fixer;
+impl Fixer {
+ pub fn fix_if_let(&self, db: &dyn SyntaxGroup, node: SyntaxNode) -> String {
+ let match_expr = ExprMatch::from_syntax_node(db, node.clone());
+ let arms = match_expr.arms(db).elements(db);
+ let first_arm = &arms[0];
+ let second_arm = &arms[1];
+ let (pattern, first_expr) =
+ match (&first_arm.patterns(db).elements(db)[0], &second_arm.patterns(db).elements(db)[0]) {
+ (Pattern::Underscore(_), Pattern::Enum(pat)) => {
+ (&pat.as_syntax_node().get_text_without_trivia(db), second_arm)
+ }
+ (Pattern::Enum(pat), Pattern::Underscore(_)) => {
+ (&pat.as_syntax_node().get_text_without_trivia(db), first_arm)
+ }
+ (Pattern::Underscore(_), Pattern::Struct(pat)) => {
+ (&pat.as_syntax_node().get_text_without_trivia(db), second_arm)
+ }
+ (Pattern::Struct(pat), Pattern::Underscore(_)) => {
+ (&pat.as_syntax_node().get_text_without_trivia(db), first_arm)
+ }
+ (_, _) => panic!("Incorrect diagnostic"),
+ };
+ format!(
+ "{}if let {} = {} {{ {} }}",
+ node.get_text(db).chars().take_while(|c| c.is_whitespace()).collect::(),
+ pattern,
+ match_expr.expr(db).as_syntax_node().get_text(db),
+ first_expr.expression(db).as_syntax_node().get_text_without_trivia(db),
+ )
+ }
+ pub fn fix_plugin_diagnostic(&self, db: &AnalysisDatabase, diag: &PluginDiagnostic) -> String {
+ match diagnostic_kind_from_message(&diag.message) {
+ RetardationKind::IfLet => self.fix_if_let(db, diag.stable_ptr.lookup(db.upcast())),
+ _ => "".to_owned(),
+ }
+ }
+}
diff --git a/crates/unretardify-core/src/lib.rs b/crates/cairo-lint-core/src/lib.rs
similarity index 100%
rename from crates/unretardify-core/src/lib.rs
rename to crates/cairo-lint-core/src/lib.rs
diff --git a/crates/cairo-lint-core/src/plugin.rs b/crates/cairo-lint-core/src/plugin.rs
new file mode 100644
index 00000000..b17557cd
--- /dev/null
+++ b/crates/cairo-lint-core/src/plugin.rs
@@ -0,0 +1,130 @@
+use std::ops::Deref;
+
+use cairo_lang_defs::ids::{ModuleId, ModuleItemId};
+use cairo_lang_defs::plugin::PluginDiagnostic;
+use cairo_lang_diagnostics::Severity;
+use cairo_lang_semantic::db::SemanticGroup;
+use cairo_lang_semantic::plugin::{AnalyzerPlugin, PluginSuite};
+use cairo_lang_syntax::node::ast::{Expr, ExprMatch, Pattern, Statement};
+use cairo_lang_syntax::node::db::SyntaxGroup;
+use cairo_lang_syntax::node::kind::SyntaxKind;
+use cairo_lang_syntax::node::{TypedStablePtr, TypedSyntaxNode};
+
+pub fn cairo_lint_plugin_suite() -> PluginSuite {
+ let mut suite = PluginSuite::default();
+ suite.add_analyzer_plugin::();
+ suite
+}
+#[derive(Debug, Default)]
+pub struct IsRetarded;
+
+#[derive(Debug, PartialEq)]
+pub enum RetardationKind {
+ IfLet,
+ If,
+ Unknown,
+}
+
+pub fn diagnostic_kind_from_message(message: &str) -> RetardationKind {
+ match message {
+ IsRetarded::IF_LET => RetardationKind::IfLet,
+ IsRetarded::IF => RetardationKind::If,
+ _ => RetardationKind::Unknown,
+ }
+}
+
+impl IsRetarded {
+ const IF_LET: &'static str =
+ "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`";
+ const IF: &'static str = "you seem to be trying to use `match` for an equality check. Consider using `if`";
+
+ pub fn check_match(&self, db: &dyn SyntaxGroup, match_expr: &ExprMatch, diagnostics: &mut Vec) {
+ let arms = match_expr.arms(db).deref().elements(db);
+ let mut is_single_armed = false;
+ let mut is_destructuring = false;
+ if arms.len() == 2 {
+ for arm in arms {
+ let patterns = arm.patterns(db).elements(db);
+ match patterns[0].clone() {
+ Pattern::Underscore(_) => {
+ let tuple_expr = match arm.expression(db) {
+ Expr::Block(block_expr) => {
+ let statements = block_expr.statements(db).elements(db);
+ if statements.len() == 1 {
+ match &statements[0] {
+ Statement::Expr(statement_expr) => {
+ if let Expr::Tuple(tuple_expr) = statement_expr.expr(db) {
+ Some(tuple_expr)
+ } else {
+ None
+ }
+ }
+ _ => None,
+ }
+ } else {
+ None
+ }
+ }
+ Expr::Tuple(tuple_expr) => Some(tuple_expr),
+ _ => None,
+ };
+ is_single_armed = tuple_expr.is_some_and(|list| list.expressions(db).elements(db).is_empty());
+ }
+
+ Pattern::Enum(pat) => {
+ is_destructuring = !pat.pattern(db).as_syntax_node().get_text(db).is_empty();
+ }
+ Pattern::Struct(pat) => {
+ is_destructuring = !pat.as_syntax_node().get_text(db).is_empty();
+ }
+ _ => (),
+ };
+ }
+ };
+ match (is_single_armed, is_destructuring) {
+ (true, false) => diagnostics.push(PluginDiagnostic {
+ stable_ptr: match_expr.stable_ptr().untyped(),
+ message: Self::IF.to_string(),
+ severity: Severity::Warning,
+ }),
+ (true, true) => diagnostics.push(PluginDiagnostic {
+ stable_ptr: match_expr.stable_ptr().untyped(),
+ message: Self::IF_LET.to_string(),
+ severity: Severity::Warning,
+ }),
+ (_, _) => (),
+ }
+ }
+}
+
+impl AnalyzerPlugin for IsRetarded {
+ fn diagnostics(&self, db: &dyn SemanticGroup, module_id: ModuleId) -> Vec {
+ let mut diags = Vec::new();
+ let Ok(items) = db.module_items(module_id) else {
+ return diags;
+ };
+ for item in items.iter() {
+ match item {
+ ModuleItemId::FreeFunction(func_id) => {
+ //
+ let func = db.module_free_function_by_id(*func_id).unwrap().unwrap();
+ let descendants = func.as_syntax_node().descendants(db.upcast());
+ for descendant in descendants.into_iter() {
+ match descendant.kind(db.upcast()) {
+ SyntaxKind::ExprMatch => self.check_match(
+ db.upcast(),
+ &ExprMatch::from_syntax_node(db.upcast(), descendant),
+ &mut diags,
+ ),
+ SyntaxKind::ItemExternFunction => (),
+ _ => (),
+ }
+ }
+ }
+ ModuleItemId::ExternFunction(_) => (),
+ _ => (),
+ }
+ }
+ diags
+ }
+}
diff --git a/crates/cairo-lint-core/tests/test_files/if_let b/crates/cairo-lint-core/tests/test_files/if_let
new file mode 100644
index 00000000..792f4480
--- /dev/null
+++ b/crates/cairo-lint-core/tests/test_files/if_let
@@ -0,0 +1,53 @@
+//! > simple if let
+
+//! > cairo_code
+fn main() {
+ let variable = Option::Some(1_felt252);
+ match variable {
+ Option::Some(a) => println!("{a}"),
+ _ => (),
+ };
+}
+
+//! > diagnostics
+warning: Plugin diagnostic: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+ --> lib.cairo:3:2
+\ match variable {
+| Option::Some(a) => println!("{a}"),
+| _ => (),
+| }
+|___^
+
+//! > fixed
+fn main() {
+ let variable = Option::Some(1_felt252);
+ if let Option::Some(a) = variable { println!("{a}") };
+}
+
+//! > ==========================================================================
+
+//! > simple if let with scope
+
+//! > cairo_code
+fn main() {
+ let variable = Option::Some(1_felt252);
+ match variable {
+ Option::Some(a) => println!("{a}"),
+ _ => { () },
+ };
+}
+
+//! > diagnostics
+warning: Plugin diagnostic: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+ --> lib.cairo:3:2
+\ match variable {
+| Option::Some(a) => println!("{a}"),
+| _ => { () },
+| }
+|___^
+
+//! > fixed
+fn main() {
+ let variable = Option::Some(1_felt252);
+ if let Option::Some(a) = variable { println!("{a}") };
+}
diff --git a/crates/unretardify-core/tests/test_files/unused_variables b/crates/cairo-lint-core/tests/test_files/unused_variables
similarity index 57%
rename from crates/unretardify-core/tests/test_files/unused_variables
rename to crates/cairo-lint-core/tests/test_files/unused_variables
index 3385259e..bd801c6c 100644
--- a/crates/unretardify-core/tests/test_files/unused_variables
+++ b/crates/cairo-lint-core/tests/test_files/unused_variables
@@ -3,8 +3,6 @@
//! > cairo_code
fn main() {
let a: Option = Option::Some(1);
- let b = 2;
- let c = 2;
}
//! > diagnostics
@@ -13,19 +11,34 @@ warning[E0001]: Unused variable. Consider ignoring by prefixing with `_`.
let a: Option = Option::Some(1);
^
+//! > fixed
+fn main() {
+ let _a: Option = Option::Some(1);
+}
+
+//! > ==========================================================================
+
+//! > two unused variable
+
+//! > cairo_code
+fn main() {
+ let a: Option = Option::Some(1);
+ let b = 1;
+}
+
+//! > diagnostics
warning[E0001]: Unused variable. Consider ignoring by prefixing with `_`.
- --> lib.cairo:3:9
- let b = 2;
+ --> lib.cairo:2:9
+ let a: Option = Option::Some(1);
^
warning[E0001]: Unused variable. Consider ignoring by prefixing with `_`.
- --> lib.cairo:4:9
- let c = 2;
+ --> lib.cairo:3:9
+ let b = 1;
^
//! > fixed
fn main() {
let _a: Option = Option::Some(1);
- let _b = 2;
- let _c = 2;
+ let _b = 1;
}
diff --git a/crates/cairo-lint-core/tests/tests.rs b/crates/cairo-lint-core/tests/tests.rs
new file mode 100644
index 00000000..6ddde794
--- /dev/null
+++ b/crates/cairo-lint-core/tests/tests.rs
@@ -0,0 +1,19 @@
+use std::cmp::Reverse;
+use std::path::Path;
+use std::sync::{LazyLock, Mutex};
+
+use cairo_lang_semantic::test_utils::setup_test_crate;
+use cairo_lang_test_utils::parse_test_file::{dump_to_test_file, parse_test_file, Test};
+use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
+use cairo_lang_utils::Upcast;
+use cairo_lint_core::db::AnalysisDatabase;
+use cairo_lint_core::fix::{fix_semantic_diagnostic, Fix};
+use cairo_lint_test_utils::{get_diags, test_file, Tests};
+use ctor::dtor;
+use paste::paste;
+use pretty_assertions::assert_eq;
+use test_case::test_case;
+
+test_file!(unused_variables, "one unused variable", "two unused variable");
+
+test_file!(if_let, "simple if let", "simple if let with scope");
diff --git a/crates/cairo-lint-core/tests/utils.rs b/crates/cairo-lint-core/tests/utils.rs
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/crates/cairo-lint-core/tests/utils.rs
@@ -0,0 +1 @@
+
diff --git a/crates/cairo-lint-test-utils/Cargo.toml b/crates/cairo-lint-test-utils/Cargo.toml
new file mode 100644
index 00000000..0344cacc
--- /dev/null
+++ b/crates/cairo-lint-test-utils/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "cairo-lint-test-utils"
+version.workspace = true
+edition.workspace = true
+repository.workspace = true
+license.workspace = true
+license-file.workspace = true
+
+[dependencies]
+cairo-lang-utils.workspace = true
+cairo-lang-test-utils.workspace = true
+cairo-lang-filesystem.workspace = true
+cairo-lang-diagnostics.workspace = true
+cairo-lang-semantic.workspace = true
+cairo-lang-defs.workspace = true
+cairo-lint-core = { path = "../cairo-lint-core" }
+paste.workspace = true
diff --git a/crates/cairo-lint-test-utils/src/lib.rs b/crates/cairo-lint-test-utils/src/lib.rs
new file mode 100644
index 00000000..856f5884
--- /dev/null
+++ b/crates/cairo-lint-test-utils/src/lib.rs
@@ -0,0 +1,91 @@
+use std::path::PathBuf;
+
+use cairo_lang_defs::db::DefsGroup;
+use cairo_lang_defs::ids::ModuleId;
+use cairo_lang_diagnostics::Diagnostics;
+use cairo_lang_filesystem::db::{init_dev_corelib, FilesGroup};
+use cairo_lang_filesystem::ids::{CrateId, FileLongId};
+use cairo_lang_semantic::db::SemanticGroup;
+use cairo_lang_semantic::SemanticDiagnostic;
+use cairo_lang_test_utils::parse_test_file::Test;
+use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
+use cairo_lang_utils::LookupIntern;
+use cairo_lint_core::db::AnalysisDatabase;
+
+pub struct Tests {
+ pub tests: OrderedHashMap,
+ pub should_fix: bool,
+}
+pub fn get_diags(crate_id: CrateId, db: &mut AnalysisDatabase) -> Vec> {
+ init_dev_corelib(db, PathBuf::from(std::env::var("CORELIB_PATH").unwrap()));
+ let mut diagnostics = Vec::new();
+ let module_file = db.module_main_file(ModuleId::CrateRoot(crate_id)).unwrap();
+ if db.file_content(module_file).is_none() {
+ match module_file.lookup_intern(db) {
+ FileLongId::OnDisk(_path) => {}
+ FileLongId::Virtual(_) => panic!("Missing virtual file."),
+ }
+ }
+
+ for module_id in &*db.crate_modules(crate_id) {
+ diagnostics.push(db.module_semantic_diagnostics(*module_id).unwrap());
+ }
+ diagnostics
+}
+#[macro_export]
+macro_rules! test_file {
+ ($file_path:ident, $($test_name:expr),*) => {
+
+ paste ! {
+
+ const []: &str = concat!("tests/test_files/", stringify!($file_path));
+ static []: LazyLock> =
+ LazyLock::new(|| parse_test_file(Path::new([])).unwrap());
+ static []: LazyLock> =
+ LazyLock::new(|| Mutex::new(Tests { tests: OrderedHashMap::default(), should_fix: false }));
+
+
+ #[dtor]
+ fn []() {
+ let val = [].lock().unwrap();
+ if val.should_fix {
+ dump_to_test_file(val.tests.clone(), []).unwrap();
+ }
+ }
+
+ $(#[test_case($test_name; $test_name)])*
+ fn $file_path(test_name: &str) {
+ let test = & [][test_name];
+ let is_fix_mode = std::env::var("FIX_TESTS") == Ok("1".into());
+ let mut file = test.attributes["cairo_code"].clone();
+ let mut db = AnalysisDatabase::new();
+ let mut fixes = Vec::new();
+
+ let diags = get_diags(setup_test_crate(db.upcast(), &file), &mut db);
+ for diag in diags.iter().flat_map(|diags| diags.get_all()) {
+ let fix = fix_semantic_diagnostic(&db, &diag);
+ if !fix.is_empty() {
+ let span = diag.stable_location.syntax_node(db.upcast()).span(db.upcast());
+ fixes.push(Fix { span, suggestion: fix });
+ }
+ }
+ fixes.sort_by_key(|v| Reverse(v.span.start));
+ for fix in fixes.iter() {
+ file.replace_range(fix.span.to_str_range(), &fix.suggestion);
+ }
+ let formatted_diags =
+ diags.into_iter().map(|diag| diag.format(db.upcast())).collect::().trim().to_string();
+ if is_fix_mode {
+ let mut new_test = test.clone();
+ new_test.attributes.insert("diagnostics".to_string(), formatted_diags.clone());
+ new_test.attributes.insert("fixed".to_string(), file.clone());
+ let mut new_tests = [].lock().unwrap();
+ new_tests.should_fix = true;
+ new_tests.tests.insert(test_name.to_string(), new_test);
+ }
+ assert_eq!(formatted_diags, test.attributes["diagnostics"]);
+ assert_eq!(file, test.attributes["fixed"]);
+ }
+ }
+ };
+}
diff --git a/crates/unretardify-core/src/fix.rs b/crates/unretardify-core/src/fix.rs
deleted file mode 100644
index cca5f010..00000000
--- a/crates/unretardify-core/src/fix.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use cairo_lang_semantic::diagnostic::SemanticDiagnosticKind;
-use cairo_lang_semantic::SemanticDiagnostic;
-use cairo_lang_utils::Upcast;
-
-use crate::db::AnalysisDatabase;
-
-#[derive(Default)]
-pub struct Fix {
- pub start: u32,
- pub end: u32,
- pub suggestion: String,
-}
-pub fn fix_semantic_diagnostic(db: &AnalysisDatabase, diag: &SemanticDiagnostic) -> String {
- // diag.stable_location.syntax_node(db.upcast()).green_node(db.upcast()).details
- match diag.kind {
- SemanticDiagnosticKind::UnusedVariable => {
- format!("_{}", diag.stable_location.syntax_node(db.upcast()).get_text(db.upcast()))
- }
-
- _ => "".to_owned(),
- }
-}
diff --git a/crates/unretardify-core/src/plugin.rs b/crates/unretardify-core/src/plugin.rs
deleted file mode 100644
index d5d33b91..00000000
--- a/crates/unretardify-core/src/plugin.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-use std::ops::Deref;
-
-use cairo_lang_defs::ids::{ModuleId, ModuleItemId};
-use cairo_lang_defs::plugin::PluginDiagnostic;
-use cairo_lang_semantic::db::SemanticGroup;
-use cairo_lang_semantic::plugin::{AnalyzerPlugin, PluginSuite};
-use cairo_lang_syntax::node::ast::{ExprMatch, Pattern};
-use cairo_lang_syntax::node::db::SyntaxGroup;
-use cairo_lang_syntax::node::kind::SyntaxKind;
-use cairo_lang_syntax::node::{TypedStablePtr, TypedSyntaxNode};
-
-pub fn unretardify_plugin_suite() -> PluginSuite {
- let mut suite = PluginSuite::default();
- suite.add_analyzer_plugin::();
- suite
-}
-#[derive(Debug, Default)]
-pub struct IsRetarded;
-
-impl IsRetarded {
- pub fn check_match(&self, db: &dyn SyntaxGroup, match_expr: &ExprMatch, diagnostics: &mut Vec) {
- let arms = match_expr.arms(db).deref().elements(db);
- let mut is_single_armed = false;
- let mut is_destructuring = false;
- if arms.len() == 2 {
- for arm in arms {
- let patterns = arm.patterns(db).elements(db);
- if let Pattern::Underscore(_term_underscore) = patterns[0].clone() {
- is_single_armed = true;
- } else if let Pattern::Enum(pat) = patterns[0].clone() {
- is_destructuring = !pat.pattern(db).as_syntax_node().get_text(db).is_empty();
- } else {
- println!("Patterns:Â {:?}", patterns);
- }
- }
- };
- match (is_single_armed, is_destructuring) {
- (true, false) => diagnostics.push(PluginDiagnostic {
- stable_ptr: match_expr.stable_ptr().untyped(),
- message: "you seem to be trying to use `match` for an equality check. Consider using `if`".to_string(),
- severity: cairo_lang_diagnostics::Severity::Warning,
- }),
- (true, true) => diagnostics.push(PluginDiagnostic {
- stable_ptr: match_expr.stable_ptr().untyped(),
- message: "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if \
- let`"
- .to_string(),
- severity: cairo_lang_diagnostics::Severity::Warning,
- }),
- (_, _) => (),
- }
- }
-}
-
-impl AnalyzerPlugin for IsRetarded {
- fn diagnostics(&self, db: &dyn SemanticGroup, module_id: ModuleId) -> Vec {
- let mut diags = Vec::new();
- let Ok(items) = db.module_items(module_id) else {
- return diags;
- };
- for item in items.iter() {
- match item {
- ModuleItemId::FreeFunction(func_id) => {
- //
- let func = db.module_free_function_by_id(*func_id).unwrap().unwrap();
- let descendants = func.as_syntax_node().descendants(db.upcast());
- for descendant in descendants.into_iter() {
- match descendant.kind(db.upcast()) {
- SyntaxKind::ExprMatch => self.check_match(
- db.upcast(),
- &ExprMatch::from_syntax_node(db.upcast(), descendant),
- &mut diags,
- ),
- SyntaxKind::ItemExternFunction => (),
- _ => (),
- }
- }
- }
- ModuleItemId::ExternFunction(_) => (),
- _ => (),
- }
- }
- diags
- }
-}
diff --git a/crates/unretardify-core/tests/unused_variables.rs b/crates/unretardify-core/tests/unused_variables.rs
deleted file mode 100644
index 65d0252d..00000000
--- a/crates/unretardify-core/tests/unused_variables.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-use std::path::{Path, PathBuf};
-use std::sync::LazyLock;
-
-use cairo_lang_defs::db::DefsGroup;
-use cairo_lang_defs::ids::ModuleId;
-use cairo_lang_diagnostics::Diagnostics;
-use cairo_lang_filesystem::db::{init_dev_corelib, FilesGroup};
-use cairo_lang_filesystem::ids::{CrateId, FileLongId};
-use cairo_lang_semantic::db::SemanticGroup;
-use cairo_lang_semantic::test_utils::setup_test_crate;
-use cairo_lang_semantic::SemanticDiagnostic;
-use cairo_lang_test_utils::parse_test_file::{dump_to_test_file, parse_test_file, Test};
-use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
-use cairo_lang_utils::{LookupIntern, Upcast};
-use pretty_assertions::assert_eq;
-use test_case::test_case;
-use unretardify_core::db::AnalysisDatabase;
-use unretardify_core::fix::{fix_semantic_diagnostic, Fix};
-
-const TEST_FILENAME: &str = "tests/unused_variables/unused_variables";
-static PARSED_TEST_FILE: LazyLock> =
- LazyLock::new(|| parse_test_file(Path::new(TEST_FILENAME)).unwrap());
-
-fn get_diags(crate_id: CrateId, db: &mut AnalysisDatabase) -> Vec> {
- init_dev_corelib(db, PathBuf::from("/Users/lucas/cairo/corelib/src"));
- let mut diagnostics = Vec::new();
- let module_file = db.module_main_file(ModuleId::CrateRoot(crate_id)).unwrap();
- if db.file_content(module_file).is_none() {
- match module_file.lookup_intern(db) {
- FileLongId::OnDisk(_path) => {}
- FileLongId::Virtual(_) => panic!("Missing virtual file."),
- }
- }
-
- for module_id in &*db.crate_modules(crate_id) {
- diagnostics.push(db.module_semantic_diagnostics(*module_id).unwrap());
- }
- diagnostics
-}
-
-#[test_case("one unused variable"; "1 unused variable")]
-fn test_unused_variable(test_name: &str) {
- let test = &PARSED_TEST_FILE[test_name];
- let is_fix_mode = std::env::var("FIX_TESTS") == Ok("1".into());
- let mut file = test.attributes["cairo_code"].clone();
- let mut db = AnalysisDatabase::new();
- let mut fixes = Vec::new();
-
- let diags = get_diags(setup_test_crate(db.upcast(), &file), &mut db);
- for diag in diags.iter().flat_map(|diags| diags.get_all()) {
- let fix = fix_semantic_diagnostic(&db, &diag);
- if !fix.is_empty() {
- let span = diag.stable_location.syntax_node(db.upcast()).span(db.upcast());
- fixes.push(Fix { start: span.start.to_u32(), end: span.end.to_u32(), suggestion: fix });
- }
- }
- let mut offset = 0;
- fixes.sort_by_key(|v| v.start);
- for fix in fixes.iter() {
- file.replace_range(offset + fix.start as usize..offset + fix.end as usize, &fix.suggestion);
- offset += fix.suggestion.len() - (fix.end - fix.start) as usize;
- }
- let formatted_diags = diags.into_iter().map(|diag| diag.format(db.upcast())).collect::().trim().to_string();
- if is_fix_mode {
- let mut new_test = test.clone();
- new_test.attributes.insert("diagnostics".to_string(), formatted_diags.clone());
- new_test.attributes.insert("fixed".to_string(), file.clone());
- let mut new_tests = PARSED_TEST_FILE.clone();
- new_tests.insert(test_name.to_string(), new_test);
- dump_to_test_file(new_tests, TEST_FILENAME).unwrap();
- }
- assert_eq!(formatted_diags, test.attributes["diagnostics"]);
- assert_eq!(file, test.attributes["fixed"]);
-}
diff --git a/resources/img/logo.jpg b/resources/img/logo.jpg
new file mode 100644
index 00000000..71d20561
Binary files /dev/null and b/resources/img/logo.jpg differ