Skip to content

Commit

Permalink
feat: support workspace diagnostics
Browse files Browse the repository at this point in the history
and fix some bugs
  • Loading branch information
mtshiba committed Jul 7, 2024
1 parent 11b3940 commit 3c46a03
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 97 deletions.
46 changes: 23 additions & 23 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ edition = "2021"
repository = "https://github.com/mtshiba/pylyzer"

[workspace.dependencies]
erg_common = { version = "0.6.40-nightly.0", features = ["py_compat", "els"] }
erg_compiler = { version = "0.6.40-nightly.0", features = ["py_compat", "els"] }
els = { version = "0.1.52-nightly.0", features = ["py_compat"] }
erg_common = { version = "0.6.40-nightly.1", features = ["py_compat", "els"] }
erg_compiler = { version = "0.6.40-nightly.1", features = ["py_compat", "els"] }
els = { version = "0.1.52-nightly.1", features = ["py_compat"] }
# rustpython-parser = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] }
# rustpython-ast = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] }
rustpython-parser = { git = "https://github.com/RustPython/Parser", version = "0.3.1", features = ["all-nodes-with-ranges", "location"] }
Expand Down
42 changes: 26 additions & 16 deletions crates/py2erg/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2048,10 +2048,11 @@ impl ASTConverter {
DefBody::new(EQUAL, Block::new(vec![call]), DefId(0)),
)
} else {
self.register_name_info(&name.name, NameKind::Variable);
let top_module = name.name.split('.').next().unwrap();
self.register_name_info(top_module, NameKind::Variable);
let var = VarSignature::new(
VarPattern::Ident(
self.convert_ident(name.name.to_string(), name.location()),
self.convert_ident(top_module.to_string(), name.location()),
),
None,
);
Expand Down Expand Up @@ -2159,20 +2160,29 @@ impl ASTConverter {
VarSignature::new(VarPattern::Ident(ident), None)
};
// from foo import bar, baz (if bar, baz is a module) ==> bar = import "foo/bar"; baz = import "foo/baz"
if let Ok(_path) = name_path {
let cont = format!("\"{module}/{}\"", name.name);
let mod_name = Expr::Literal(Literal::new(Token::new(
TokenKind::StrLit,
cont,
location.row.get(),
location.column.to_zero_indexed(),
)));
let call = import_acc.clone().call1(mod_name);
let def = Def::new(
Signature::Var(alias),
DefBody::new(EQUAL, Block::new(vec![call]), DefId(0)),
);
exprs.push(Expr::Def(def));
if let Ok(mut path) = name_path {
if path.ends_with("__init__.py") {
path.pop();
}
let mod_name = path.file_name().unwrap();
if name.name.as_str() == mod_name.to_string_lossy().trim_end_matches(".py") {
let cont = format!("\"{module}/{}\"", name.name);
let mod_name = Expr::Literal(Literal::new(Token::new(
TokenKind::StrLit,
cont,
location.row.get(),
location.column.to_zero_indexed(),
)));
let call = import_acc.clone().call1(mod_name);
let def = Def::new(
Signature::Var(alias),
DefBody::new(EQUAL, Block::new(vec![call]), DefId(0)),
);
exprs.push(Expr::Def(def));
} else {
// name.name: Foo, file_name: foo.py
imports.push(VarRecordAttr::new(true_name, alias));
}
} else {
imports.push(VarRecordAttr::new(true_name, alias));
}
Expand Down
73 changes: 38 additions & 35 deletions crates/py2erg/gen_decl.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use std::fs::File;
use std::fs::{create_dir_all, File};
use std::io::{BufWriter, Write};
use std::path::Path;

use erg_common::io::Input;
use erg_common::pathutil::mod_name;
use erg_common::pathutil::{mod_name, NormalizedPathBuf};
use erg_common::set::Set;
use erg_common::traits::LimitedDisplay;
use erg_common::{log, Str};
use erg_compiler::build_package::{CheckStatus, PylyzerStatus};
use erg_compiler::hir::{ClassDef, Expr, HIR};
use erg_compiler::module::SharedModuleCache;
use erg_compiler::ty::value::{GenTypeObj, TypeObj};
use erg_compiler::ty::{HasType, Type};

Expand All @@ -29,30 +29,33 @@ pub struct DeclFileGenerator {
}

impl DeclFileGenerator {
pub fn new(input: &Input, status: CheckStatus) -> Self {
pub fn new(path: &NormalizedPathBuf, status: CheckStatus) -> Self {
let (timestamp, hash) = {
let py_file_path = input.path();
let metadata = std::fs::metadata(py_file_path).unwrap();
let metadata = std::fs::metadata(path).unwrap();
let dummy_hash = metadata.len();
(metadata.modified().unwrap(), dummy_hash)
};
let status = PylyzerStatus {
status,
file: input.path().into(),
file: path.to_path_buf(),
timestamp,
hash,
};
let code = format!("{status}\n");
Self {
filename: input.filename().replace(".py", ".d.er"),
filename: path
.file_name()
.unwrap()
.to_string_lossy()
.replace(".py", ".d.er"),
namespace: "".to_string(),
imported: Set::new(),
code,
}
}

pub fn gen_decl_er(mut self, hir: HIR) -> DeclFile {
for chunk in hir.module.into_iter() {
pub fn gen_decl_er(mut self, hir: &HIR) -> DeclFile {
for chunk in hir.module.iter() {
self.gen_chunk_decl(chunk);
}
log!("code:\n{}", self.code);
Expand All @@ -62,7 +65,7 @@ impl DeclFileGenerator {
}
}

fn gen_chunk_decl(&mut self, chunk: Expr) {
fn gen_chunk_decl(&mut self, chunk: &Expr) {
match chunk {
Expr::Def(def) => {
let mut name = def
Expand Down Expand Up @@ -142,13 +145,13 @@ impl DeclFileGenerator {
self.code += &decl;
}
}
for attr in ClassDef::take_all_methods(def.methods_list) {
for attr in ClassDef::get_all_methods(&def.methods_list) {
self.gen_chunk_decl(attr);
}
self.namespace = stash;
}
Expr::Dummy(dummy) => {
for chunk in dummy.into_iter() {
for chunk in dummy.iter() {
self.gen_chunk_decl(chunk);
}
}
Expand All @@ -158,31 +161,31 @@ impl DeclFileGenerator {
}
}

pub fn reserve_decl_er(input: Input) {
let mut dir = input.dir();
dir.push("__pycache__");
let pycache_dir = dir.as_path();
if !pycache_dir.exists() {
std::fs::create_dir(pycache_dir).unwrap();
fn dump_decl_er(path: &NormalizedPathBuf, hir: &HIR, status: CheckStatus) {
let decl_gen = DeclFileGenerator::new(path, status);
let file = decl_gen.gen_decl_er(hir);
let Some(dir) = path.parent().and_then(|p| p.canonicalize().ok()) else {
return;
};
let cache_dir = dir.join("__pycache__");
if !cache_dir.exists() {
let _ = create_dir_all(&cache_dir);
}
let filename = input.filename();
let mut path = pycache_dir.join(filename);
path.set_extension("d.er");
let path = cache_dir.join(file.filename);
if !path.exists() {
let _f = File::create(path).unwrap();
let _f = File::create(&path);
}
let Ok(f) = File::options().write(true).open(path) else {
return;
};
let mut f = BufWriter::new(f);
let _ = f.write_all(file.code.as_bytes());
}

pub fn dump_decl_er(input: Input, hir: HIR, status: CheckStatus) {
let decl_gen = DeclFileGenerator::new(&input, status);
let file = decl_gen.gen_decl_er(hir);
let mut dir = input.dir();
dir.push("__pycache__");
let pycache_dir = dir.as_path();
let f = File::options()
.write(true)
.open(pycache_dir.join(file.filename))
.unwrap();
let mut f = BufWriter::new(f);
f.write_all(file.code.as_bytes()).unwrap();
pub fn dump_decl_package(modules: &SharedModuleCache) {
for (path, module) in modules.raw_iter() {
if let Some(hir) = module.hir.as_ref() {
dump_decl_er(path, hir, module.status);
}
}
}
8 changes: 6 additions & 2 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "pylyzer",
"description": "A fast Python static code analyzer & language server for VSCode",
"publisher": "pylyzer",
"version": "0.1.7",
"version": "0.1.8",
"engines": {
"vscode": "^1.70.0"
},
Expand All @@ -14,7 +14,11 @@
},
"icon": "images/pylyzer-logo.png",
"main": "./dist/extension.js",
"activationEvents": ["onLanguage:python"],
"activationEvents": [
"workspaceContains:pyproject.toml",
"workspaceContains:*/pyproject.toml",
"onLanguage:python"
],
"contributes": {
"commands": [
{
Expand Down
Loading

0 comments on commit 3c46a03

Please sign in to comment.