fix: type declaration bugs

This commit is contained in:
Shunsuke Shibayama 2023-06-04 16:48:21 +09:00
parent 446262d74c
commit a8abb7709e
7 changed files with 87 additions and 41 deletions

View file

@ -8,7 +8,9 @@ use erg_common::traits::Stream;
use erg_compiler::artifact::BuildRunnable;
use erg_compiler::error::CompileErrors;
use lsp_types::{Diagnostic, DiagnosticSeverity, Position, PublishDiagnosticsParams, Range, Url};
use lsp_types::{
Diagnostic, DiagnosticSeverity, NumberOrString, Position, PublishDiagnosticsParams, Range, Url,
};
use crate::diff::{ASTDiff, HIRDiff};
use crate::server::{send, send_log, AnalysisResult, DefaultFeatures, ELSResult, Server};
@ -151,7 +153,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
let diag = Diagnostic::new(
Range::new(start, end),
Some(severity),
None,
Some(NumberOrString::String(format!("E{}", err.core.errno))),
None,
message,
None,

View file

@ -164,6 +164,20 @@ impl InputKind {
PathBuf::from(".")
}
}
pub fn project_root(&self) -> Option<PathBuf> {
if let Self::File(path) = self {
let mut parent = path.clone();
while parent.pop() {
if parent.join("package.er").exists() {
return Some(parent);
}
}
None
} else {
None
}
}
}
/// Since input is not always only from files
@ -232,6 +246,10 @@ impl Input {
self.kind.dir()
}
pub fn project_root(&self) -> Option<PathBuf> {
self.kind.project_root()
}
pub fn enclosed_name(&self) -> &str {
self.kind.enclosed_name()
}
@ -484,10 +502,10 @@ impl Input {
Ok(normalize_path(path))
}
fn resolve_local_decl(&self, path: &Path) -> Result<PathBuf, std::io::Error> {
self._resolve_local_decl(path).or_else(|_| {
fn resolve_local_decl(&self, dir: PathBuf, path: &Path) -> Result<PathBuf, std::io::Error> {
self._resolve_local_decl(dir.clone(), path).or_else(|_| {
let path = add_postfix_foreach(path, ".d");
self._resolve_local_decl(&path)
self._resolve_local_decl(dir, &path)
})
}
@ -496,8 +514,11 @@ impl Input {
/// 2. `{path/to}/__init__.d.er`
/// 3. `{path}/__pycache__/{to}.d.er`
/// 4. `{path/to}/__pycache__/__init__.d.er`
fn _resolve_local_decl(&self, path: &Path) -> Result<PathBuf, std::io::Error> {
let mut dir = self.dir();
fn _resolve_local_decl(
&self,
mut dir: PathBuf,
path: &Path,
) -> Result<PathBuf, std::io::Error> {
let mut comps = path.components();
let last = comps
.next_back()
@ -611,27 +632,33 @@ impl Input {
/// 4. `{path/to}/__pycache__/__init__.d.er`
/// 5. `{path.d/to.d}/__init__.d.er`
/// 6. `{path.d/to.d}/__pycache__/__init__.d.er`
/// (and repeat for the project root)
/// 7. `std/{path/to}.d.er`
/// 8. `std/{path/to}/__init__.d.er`
/// 9. `site-packages/{path}/__pycache__/{to}.d.er`
/// 10. `site-packages/{path/to}/__pycache__/__init__.d.er`
pub fn resolve_decl_path(&self, path: &Path) -> Option<PathBuf> {
if let Ok(path) = self.resolve_local_decl(path) {
Some(path)
} else {
let py_roots = [erg_pystd_path, erg_py_external_lib_path];
for root in py_roots {
if let Some(path) = Self::resolve_std_decl_path(root(), path) {
return Some(path);
}
}
for site_packages in python_site_packages() {
if let Some(path) = Self::resolve_site_pkgs_decl_path(site_packages, path) {
return Some(path);
}
}
None
if let Ok(path) = self.resolve_local_decl(self.dir(), path) {
return Some(path);
}
// e.g. root: lib/external/pandas.d, path: pandas/core/frame
if let Some(dir) = self.project_root().as_ref().and_then(|root| root.parent()) {
if let Ok(path) = self.resolve_local_decl(dir.to_path_buf(), path) {
return Some(path);
}
}
let py_roots = [erg_pystd_path, erg_py_external_lib_path];
for root in py_roots {
if let Some(path) = Self::resolve_std_decl_path(root(), path) {
return Some(path);
}
}
for site_packages in python_site_packages() {
if let Some(path) = Self::resolve_site_pkgs_decl_path(site_packages, path) {
return Some(path);
}
}
None
}
/// 1. `site-packages/{path/to}.d.er`

View file

@ -2550,28 +2550,32 @@ impl Context {
mono(format!("{}{vis}{}", self.name, ident.inspect()))
}
pub(crate) fn get_namespace_path(&self, namespace: &Str) -> Option<PathBuf> {
let mut namespaces = namespace.split_with(&[".", "::"]);
let mut str_namespace = namespaces.first().map(|n| n.to_string())?;
namespaces.remove(0);
while str_namespace.is_empty() || str_namespace.ends_with('.') {
if namespaces.is_empty() {
break;
}
str_namespace.push('.');
str_namespace.push_str(namespaces.remove(0));
}
let path = Path::new(&str_namespace);
let mut path = self.cfg.input.resolve_path(path)?;
for p in namespaces.into_iter() {
path = Input::try_push_path(path, Path::new(p)).ok()?;
}
Some(path)
}
pub(crate) fn get_namespace(&self, namespace: &Str) -> Option<&Context> {
if &namespace[..] == "global" {
return self.get_builtins();
} else if &namespace[..] == "module" {
return self.get_module();
}
let mut namespaces = namespace.split_with(&[".", "::"]);
let mut namespace = namespaces.first().map(|n| n.to_string())?;
namespaces.remove(0);
while namespace.is_empty() || namespace.ends_with('.') {
if namespaces.is_empty() {
break;
}
namespace.push('.');
namespace.push_str(namespaces.remove(0));
}
let path = Path::new(&namespace);
let mut path = self.cfg.input.resolve_path(path)?;
for p in namespaces.into_iter() {
path = Input::try_push_path(path, Path::new(p)).ok()?;
}
self.get_ctx_from_path(path.as_path())
self.get_ctx_from_path(self.get_namespace_path(namespace)?.as_path())
}
pub(crate) fn get_mono_type(&self, name: &Str) -> Option<(&Type, &Context)> {

View file

@ -572,7 +572,7 @@ impl Context {
tmp_tv_cache: &mut TyVarCache,
not_found_is_qvar: bool,
) -> TyCheckResult<Type> {
match poly_spec.acc.to_string().trim_start_matches("::") {
match poly_spec.acc.to_string().trim_start_matches([':', '.']) {
"Array" => {
// TODO: kw
let mut args = poly_spec.args.pos_args();

View file

@ -1292,7 +1292,6 @@ impl Context {
}
self.register_gen_mono_type(ident, gen, ctx, Const)
} else {
log!(err "{:?}", gen.typ().typarams());
let params = gen
.typ()
.typarams()

View file

@ -663,6 +663,20 @@ impl ASTLowerer {
if ident.is_raw() {
return Ok(());
}
if self
.module
.context
.registered_info(ident.inspect(), ident.is_const())
.is_some_and(|(_, vi)| !vi.kind.is_builtin())
{
return Err(LowerErrors::from(LowerError::reassign_error(
self.cfg().input.clone(),
line!() as usize,
ident.loc(),
self.module.context.caused_by(),
ident.inspect(),
)));
}
let new_ident = if PYTHON_MODE {
let mut symbol = ident.name.clone().into_token();
symbol.content = py_name.clone();

View file

@ -146,7 +146,7 @@ impl OwnershipChecker {
// TODO: referenced
Expr::Call(call) => {
let sig_t = call.signature_t().unwrap();
if sig_t.is_failure() || sig_t.is_class_type() {
if !sig_t.is_subr() {
return;
}
let args_owns = sig_t.args_ownership();