mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 10:49:54 +00:00
fix: type declaration bugs
This commit is contained in:
parent
446262d74c
commit
a8abb7709e
7 changed files with 87 additions and 41 deletions
|
@ -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,
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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)> {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue