feat(els): add lint option

This commit is contained in:
Shunsuke Shibayama 2024-04-12 11:47:16 +09:00
parent c05432f141
commit b17b802223
6 changed files with 30 additions and 8 deletions

1
Cargo.lock generated
View file

@ -98,6 +98,7 @@ version = "0.1.47-nightly.0"
dependencies = [
"erg_common",
"erg_compiler",
"erg_linter",
"erg_proc_macros",
"lsp-types",
"molc",

View file

@ -84,7 +84,7 @@ erg_common = { workspace = true }
erg_parser = { workspace = true }
erg_compiler = { workspace = true }
erg_linter = { workspace = true }
els = { workspace = true, optional = true }
els = { workspace = true, optional = true, features = ["lint"] }
[build-dependencies]
erg_common = { workspace = true }

View file

@ -20,10 +20,12 @@ large_thread = ["erg_common/large_thread", "erg_compiler/large_thread"]
py_compat = ["erg_compiler/py_compat"]
experimental = ["erg_common/experimental", "erg_compiler/experimental"]
backtrace = ["erg_common/backtrace", "molc/debug"]
lint = ["dep:erg_linter"]
[dependencies]
erg_common = { workspace = true, features = ["els"] }
erg_compiler = { workspace = true, features = ["els"] }
erg_linter = { workspace = true, optional = true }
molc = { version = "0.2" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.85"

View file

@ -117,6 +117,18 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
let mut checker = self.get_checker(path.clone());
let (artifact, status) = match checker.build(code.into(), mode) {
Ok(artifact) => {
#[cfg(feature = "lint")]
let mut artifact = artifact;
#[cfg(feature = "lint")]
if self
.opt_features
.contains(&crate::server::OptionalFeatures::Lint)
{
use erg_common::traits::Stream;
let mut linter = erg_linter::Linter::new(self.cfg.inherit(path.clone()));
let warns = linter.lint(&artifact.object);
artifact.warns.extend(warns);
}
_log!(
self,
"checking {uri} passed, found warns: {}",

View file

@ -126,12 +126,14 @@ impl From<&str> for DefaultFeatures {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OptionalFeatures {
CheckOnType,
Lint,
}
impl From<&str> for OptionalFeatures {
fn from(s: &str) -> Self {
match s {
"checkontype" | "checkOnType" | "check-on-type" => OptionalFeatures::CheckOnType,
"lint" | "linting" => OptionalFeatures::Lint,
_ => panic!("unknown feature: {s}"),
}
}

View file

@ -8,7 +8,7 @@ use erg_common::traits::{BlockKind, ExitStatus, Locational, New, Runnable, Strea
use erg_compiler::artifact::{Buildable, ErrorArtifact};
use erg_compiler::build_package::PackageBuilder;
use erg_compiler::error::{CompileError, CompileErrors, CompileWarnings};
use erg_compiler::hir::{Accessor, Def, Dict, Expr, List, Literal, Set, Signature, Tuple};
use erg_compiler::hir::{Accessor, Def, Dict, Expr, List, Literal, Set, Signature, Tuple, HIR};
use erg_compiler::module::SharedCompilerResource;
use erg_compiler::ty::ValueObj;
@ -83,7 +83,7 @@ impl Runnable for Linter {
}
fn eval(&mut self, src: String) -> Result<String, CompileErrors> {
let warns = self.lint(src).map_err(|eart| {
let warns = self.lint_from_string(src).map_err(|eart| {
eart.warns.write_all_stderr();
eart.errors
})?;
@ -140,19 +140,24 @@ impl Linter {
pub fn lint_module(&mut self) -> Result<CompileWarnings, ErrorArtifact> {
let src = self.input().read();
self.lint(src)
self.lint_from_string(src)
}
pub fn lint(&mut self, src: String) -> Result<CompileWarnings, ErrorArtifact> {
log!(info "Start linting");
pub fn lint_from_string(&mut self, src: String) -> Result<CompileWarnings, ErrorArtifact> {
let art = self.builder.build(src, "exec")?;
self.warns.extend(art.warns);
for chunk in art.object.module.iter() {
let warns = self.lint(&art.object);
Ok(warns)
}
pub fn lint(&mut self, hir: &HIR) -> CompileWarnings {
log!(info "Start linting");
for chunk in hir.module.iter() {
self.lint_too_many_params(chunk);
self.lint_bool_comparison(chunk);
}
log!(info "Finished linting");
Ok(self.warns.take())
self.warns.take()
}
fn lint_too_many_params(&mut self, expr: &Expr) {