mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 04:09:05 +00:00
chore: remove __new__
This commit is contained in:
parent
ca140680db
commit
f8b7717682
10 changed files with 131 additions and 43 deletions
|
@ -3476,9 +3476,9 @@ impl PyCodeGenerator {
|
|||
.get_def("__init__")
|
||||
.or_else(|| methods.get_def("__init__!"))
|
||||
.cloned();
|
||||
self.emit_init_method(&class.sig, __init__, class.__new__.clone());
|
||||
self.emit_init_method(&class.sig, __init__, class.constructor.clone());
|
||||
if class.need_to_gen_new {
|
||||
self.emit_new_func(&class.sig, class.__new__);
|
||||
self.emit_new_func(&class.sig, class.constructor);
|
||||
}
|
||||
let __del__ = methods
|
||||
.remove_def("__del__")
|
||||
|
@ -3526,16 +3526,16 @@ impl PyCodeGenerator {
|
|||
unit.codeobj
|
||||
}
|
||||
|
||||
fn emit_init_method(&mut self, sig: &Signature, __init__: Option<Def>, __new__: Type) {
|
||||
fn emit_init_method(&mut self, sig: &Signature, __init__: Option<Def>, constructor: Type) {
|
||||
log!(info "entered {}", fn_name!());
|
||||
let new_first_param = __new__.non_default_params().unwrap().first();
|
||||
let new_first_param = constructor.non_default_params().unwrap().first();
|
||||
let line = sig.ln_begin().unwrap_or(0);
|
||||
let class_name = sig.ident().inspect();
|
||||
let mut ident = Identifier::public_with_line(DOT, Str::ever("__init__"), line);
|
||||
ident.vi.t = __new__.clone();
|
||||
ident.vi.t = constructor.clone();
|
||||
let self_param = VarName::from_str_and_line(Str::ever("self"), line);
|
||||
let vi = VarInfo::nd_parameter(
|
||||
__new__.return_t().unwrap().clone(),
|
||||
constructor.return_t().unwrap().clone(),
|
||||
ident.vi.def_loc.clone(),
|
||||
"?".into(),
|
||||
);
|
||||
|
@ -3622,16 +3622,16 @@ impl PyCodeGenerator {
|
|||
|
||||
/// ```python
|
||||
/// class C:
|
||||
/// # __new__ => C
|
||||
/// # constructor => C
|
||||
/// def new(x): return C(x)
|
||||
/// ```
|
||||
fn emit_new_func(&mut self, sig: &Signature, __new__: Type) {
|
||||
fn emit_new_func(&mut self, sig: &Signature, constructor: Type) {
|
||||
log!(info "entered {}", fn_name!());
|
||||
let class_ident = sig.ident();
|
||||
let line = sig.ln_begin().unwrap_or(0);
|
||||
let mut ident = Identifier::public_with_line(DOT, Str::ever("new"), line);
|
||||
let class = Expr::Accessor(Accessor::Ident(class_ident.clone()));
|
||||
ident.vi.t = __new__;
|
||||
ident.vi.t = constructor;
|
||||
if let Some(new_first_param) = ident.vi.t.non_default_params().unwrap().first() {
|
||||
let param_name = new_first_param
|
||||
.name()
|
||||
|
|
|
@ -167,6 +167,27 @@ impl Context {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn get_current_scope_attr(&self, name: &VarName) -> Option<&VarInfo> {
|
||||
#[cfg(feature = "py_compat")]
|
||||
let search_name = self
|
||||
.erg_to_py_names
|
||||
.get(name.inspect())
|
||||
.unwrap_or(name.inspect());
|
||||
#[cfg(not(feature = "py_compat"))]
|
||||
let search_name = name.inspect();
|
||||
self.locals
|
||||
.get(search_name)
|
||||
.or_else(|| self.decls.get(search_name))
|
||||
.or_else(|| {
|
||||
for methods in self.methods_list.iter() {
|
||||
if let Some(vi) = methods.get_current_scope_attr(name) {
|
||||
return Some(vi);
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn get_method_context_of(&self, trait_: &Type) -> Option<&MethodContext> {
|
||||
#[allow(clippy::manual_find)]
|
||||
for methods in self.methods_list.iter() {
|
||||
|
|
|
@ -264,6 +264,22 @@ impl TypeContext {
|
|||
pub const fn new(typ: Type, ctx: Context) -> Self {
|
||||
Self { typ, ctx }
|
||||
}
|
||||
|
||||
pub(crate) fn get_class_attr<'c>(
|
||||
&'c self,
|
||||
name: &VarName,
|
||||
ctx: &'c Context,
|
||||
) -> Option<&'c VarInfo> {
|
||||
self.get_current_scope_attr(name).or_else(|| {
|
||||
let sups = ctx.get_nominal_super_type_ctxs(&self.typ)?;
|
||||
for sup in sups {
|
||||
if let Some(vi) = sup.get_current_scope_attr(name) {
|
||||
return Some(vi);
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
|
|
@ -31,7 +31,7 @@ use crate::ty::{
|
|||
};
|
||||
|
||||
use crate::context::{ClassDefType, Context, ContextKind, DefaultInfo, RegistrationMode};
|
||||
use crate::error::readable_name;
|
||||
use crate::error::{concat_result, readable_name};
|
||||
use crate::error::{
|
||||
CompileError, CompileErrors, CompileResult, TyCheckError, TyCheckErrors, TyCheckResult,
|
||||
};
|
||||
|
@ -1337,6 +1337,8 @@ impl Context {
|
|||
}
|
||||
|
||||
/// e.g. `::__call__`
|
||||
///
|
||||
/// NOTE: this is same as `register_auto_impl` if `PYTHON_MODE` is true
|
||||
fn register_fixed_auto_impl(
|
||||
&mut self,
|
||||
name: &'static str,
|
||||
|
@ -1346,6 +1348,11 @@ impl Context {
|
|||
py_name: Option<Str>,
|
||||
) -> CompileResult<()> {
|
||||
let name = VarName::from_static(name);
|
||||
let kind = if PYTHON_MODE {
|
||||
VarKind::Auto
|
||||
} else {
|
||||
VarKind::FixedAuto
|
||||
};
|
||||
if self.locals.get(&name).is_some() {
|
||||
Err(CompileErrors::from(CompileError::reassign_error(
|
||||
self.cfg.input.clone(),
|
||||
|
@ -1361,7 +1368,7 @@ impl Context {
|
|||
t,
|
||||
muty,
|
||||
vis,
|
||||
VarKind::FixedAuto,
|
||||
kind,
|
||||
None,
|
||||
self.kind.clone(),
|
||||
py_name,
|
||||
|
@ -1607,8 +1614,9 @@ impl Context {
|
|||
2,
|
||||
self.level,
|
||||
);
|
||||
self.gen_class_new_method(&gen, call, &mut ctx)?;
|
||||
self.register_gen_mono_type(ident, gen, ctx, Const)
|
||||
let res = self.gen_class_new_method(&gen, call, &mut ctx);
|
||||
let res2 = self.register_gen_mono_type(ident, gen, ctx, Const);
|
||||
concat_result(res, res2)
|
||||
} else {
|
||||
let params = gen
|
||||
.typ()
|
||||
|
@ -1627,11 +1635,13 @@ impl Context {
|
|||
2,
|
||||
self.level,
|
||||
);
|
||||
self.gen_class_new_method(&gen, call, &mut ctx)?;
|
||||
self.register_gen_poly_type(ident, gen, ctx, Const)
|
||||
let res = self.gen_class_new_method(&gen, call, &mut ctx);
|
||||
let res2 = self.register_gen_poly_type(ident, gen, ctx, Const);
|
||||
concat_result(res, res2)
|
||||
}
|
||||
}
|
||||
GenTypeObj::Subclass(_) => {
|
||||
let mut errs = CompileErrors::empty();
|
||||
if gen.typ().is_monomorphic() {
|
||||
let super_classes = vec![gen.base_or_sup().unwrap().typ().clone()];
|
||||
// let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect();
|
||||
|
@ -1643,7 +1653,7 @@ impl Context {
|
|||
self.level,
|
||||
);
|
||||
for sup in super_classes.into_iter() {
|
||||
let sup_ctx = self.get_nominal_type_ctx(&sup).ok_or_else(|| {
|
||||
let sup_ctx = match self.get_nominal_type_ctx(&sup).ok_or_else(|| {
|
||||
TyCheckErrors::from(TyCheckError::type_not_found(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1651,7 +1661,13 @@ impl Context {
|
|||
self.caused_by(),
|
||||
&sup,
|
||||
))
|
||||
})?;
|
||||
}) {
|
||||
Ok(ctx) => ctx,
|
||||
Err(es) => {
|
||||
errs.extend(es);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
ctx.register_superclass(sup, sup_ctx);
|
||||
}
|
||||
let mut methods =
|
||||
|
@ -1669,40 +1685,58 @@ impl Context {
|
|||
..
|
||||
} = additional
|
||||
{
|
||||
self.register_instance_attrs(&mut ctx, rec, call)?;
|
||||
if let Err(es) = self.register_instance_attrs(&mut ctx, rec, call) {
|
||||
errs.extend(es);
|
||||
}
|
||||
}
|
||||
param_t
|
||||
.map(|t| self.intersection(t, additional.typ()))
|
||||
.or(Some(additional.typ().clone()))
|
||||
} else {
|
||||
param_t.cloned()
|
||||
self.get_nominal_type_ctx(sup.typ())
|
||||
.and_then(|ctx| {
|
||||
ctx.get_class_attr(&VarName::from_static("__call__"), ctx)
|
||||
})
|
||||
.and_then(|vi| vi.t.param_ts().first().cloned())
|
||||
.or(param_t.cloned())
|
||||
};
|
||||
let new_t = if let Some(t) = param_t {
|
||||
func1(t, gen.typ().clone())
|
||||
} else {
|
||||
func0(gen.typ().clone())
|
||||
};
|
||||
methods.register_fixed_auto_impl(
|
||||
if let Err(es) = methods.register_fixed_auto_impl(
|
||||
"__call__",
|
||||
new_t.clone(),
|
||||
Immutable,
|
||||
Visibility::private(ctx.name.clone()),
|
||||
None,
|
||||
)?;
|
||||
) {
|
||||
errs.extend(es);
|
||||
}
|
||||
// 必要なら、ユーザーが独自に上書きする
|
||||
methods.register_auto_impl(
|
||||
if let Err(es) = methods.register_auto_impl(
|
||||
"new",
|
||||
new_t,
|
||||
Immutable,
|
||||
Visibility::public(ctx.name.clone()),
|
||||
None,
|
||||
)?;
|
||||
) {
|
||||
errs.extend(es);
|
||||
}
|
||||
ctx.methods_list.push(MethodContext::new(
|
||||
DefId(0),
|
||||
ClassDefType::Simple(gen.typ().clone()),
|
||||
methods,
|
||||
));
|
||||
self.register_gen_mono_type(ident, gen, ctx, Const)
|
||||
if let Err(es) = self.register_gen_mono_type(ident, gen, ctx, Const) {
|
||||
errs.extend(es);
|
||||
}
|
||||
if errs.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errs)
|
||||
}
|
||||
} else {
|
||||
let class_name = gen.base_or_sup().unwrap().typ().local_name();
|
||||
Err(CompileErrors::from(CompileError::no_type_error(
|
||||
|
@ -1733,14 +1767,17 @@ impl Context {
|
|||
2,
|
||||
self.level,
|
||||
);
|
||||
if let Some(TypeObj::Builtin {
|
||||
let res = if let Some(TypeObj::Builtin {
|
||||
t: Type::Record(req),
|
||||
..
|
||||
}) = gen.base_or_sup()
|
||||
{
|
||||
self.register_instance_attrs(&mut ctx, req, call)?;
|
||||
}
|
||||
self.register_gen_mono_type(ident, gen, ctx, Const)
|
||||
self.register_instance_attrs(&mut ctx, req, call)
|
||||
} else {
|
||||
Ok(())
|
||||
};
|
||||
let res2 = self.register_gen_mono_type(ident, gen, ctx, Const);
|
||||
concat_result(res, res2)
|
||||
} else {
|
||||
feature_error!(
|
||||
CompileErrors,
|
||||
|
@ -1771,9 +1808,11 @@ impl Context {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(additional) = additional {
|
||||
self.register_instance_attrs(&mut ctx, additional, call)?;
|
||||
}
|
||||
let res = if let Some(additional) = additional {
|
||||
self.register_instance_attrs(&mut ctx, additional, call)
|
||||
} else {
|
||||
Ok(())
|
||||
};
|
||||
for sup in super_classes.into_iter() {
|
||||
if let Some(sup_ctx) = self.get_nominal_type_ctx(&sup) {
|
||||
ctx.register_supertrait(sup, sup_ctx);
|
||||
|
@ -1781,7 +1820,8 @@ impl Context {
|
|||
log!(err "{sup} not found");
|
||||
}
|
||||
}
|
||||
self.register_gen_mono_type(ident, gen, ctx, Const)
|
||||
let res2 = self.register_gen_mono_type(ident, gen, ctx, Const);
|
||||
concat_result(res, res2)
|
||||
} else {
|
||||
feature_error!(
|
||||
CompileErrors,
|
||||
|
|
|
@ -20,6 +20,18 @@ pub use crate::error::tycheck::*;
|
|||
use crate::hir::Expr;
|
||||
use crate::ty::HasType;
|
||||
|
||||
pub(crate) fn concat_result(l: CompileResult<()>, r: CompileResult<()>) -> CompileResult<()> {
|
||||
match (l, r) {
|
||||
(Ok(()), Ok(())) => Ok(()),
|
||||
(Ok(()), Err(r)) => Err(r),
|
||||
(Err(l), Ok(())) => Err(l),
|
||||
(Err(mut l), Err(mut r)) => {
|
||||
l.0.append(&mut r.0);
|
||||
Err(l)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `unreachable!(self: Context)`
|
||||
#[macro_export]
|
||||
macro_rules! unreachable_error {
|
||||
|
|
|
@ -2435,7 +2435,7 @@ pub struct ClassDef {
|
|||
pub require_or_sup: Option<Box<Expr>>,
|
||||
/// The type of `new` that is automatically defined if not defined
|
||||
pub need_to_gen_new: bool,
|
||||
pub __new__: Type,
|
||||
pub constructor: Type,
|
||||
pub methods_list: Vec<Methods>,
|
||||
}
|
||||
|
||||
|
@ -2488,7 +2488,7 @@ impl ClassDef {
|
|||
sig: Signature,
|
||||
require_or_sup: Option<Expr>,
|
||||
need_to_gen_new: bool,
|
||||
__new__: Type,
|
||||
constructor: Type,
|
||||
methods_list: Vec<Methods>,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -2496,7 +2496,7 @@ impl ClassDef {
|
|||
sig,
|
||||
require_or_sup: require_or_sup.map(Box::new),
|
||||
need_to_gen_new,
|
||||
__new__,
|
||||
constructor,
|
||||
methods_list,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
time = pyimport "time"
|
||||
{StructTime;} = pyimport "time"
|
||||
|
||||
.MINYEAR: {1}
|
||||
.MAXYEAR: {9999}
|
||||
|
@ -36,7 +36,7 @@ time = pyimport "time"
|
|||
fromisoformat: (date_string: Str) -> .Date
|
||||
fromisocalendar: (year: Nat, week: Nat, day: Nat) -> .Date
|
||||
replace: (self: .Date, year := Nat, month := Nat, day := Nat) -> .Date
|
||||
timetuple: (self: .Date) -> time.StructTime
|
||||
timetuple: (self: .Date) -> StructTime
|
||||
toordinal: (self: .Date) -> Nat
|
||||
weekday: (self: .Date) -> 0..6
|
||||
isoweekday: (self: .Date) -> 1..7
|
||||
|
|
|
@ -2301,9 +2301,8 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
|||
self.errs.extend(err);
|
||||
}
|
||||
}
|
||||
let Some(__new__) = class_ctx
|
||||
.get_current_scope_var(&VarName::from_static("__new__"))
|
||||
.or(class_ctx.get_current_scope_var(&VarName::from_static("__call__")))
|
||||
let Some(constructor) =
|
||||
class_ctx.get_class_attr(&VarName::from_static("__call__"), &self.module.context)
|
||||
else {
|
||||
return unreachable_error!(LowerErrors, LowerError, self);
|
||||
};
|
||||
|
@ -2316,7 +2315,7 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
|||
hir_def.sig,
|
||||
require_or_sup,
|
||||
need_to_gen_new,
|
||||
__new__.t.clone(),
|
||||
constructor.t.clone(),
|
||||
hir_methods_list,
|
||||
))
|
||||
}
|
||||
|
|
|
@ -1157,7 +1157,7 @@ impl PyScriptGenerator {
|
|||
"{}def __init__(self, param__):\n",
|
||||
" ".repeat(self.level + 1)
|
||||
);
|
||||
match classdef.__new__.non_default_params().unwrap()[0].typ() {
|
||||
match classdef.constructor.non_default_params().unwrap()[0].typ() {
|
||||
Type::Record(rec) => {
|
||||
for field in rec.keys() {
|
||||
let vis = if field.vis.is_private() { "__" } else { "" };
|
||||
|
|
|
@ -125,7 +125,7 @@ fn exec_invalid_class_inheritable() -> Result<(), ()> {
|
|||
"Point3d.",
|
||||
"@Override",
|
||||
"new(x, y, z) =",
|
||||
"Point3d::__new__{x; y; z}",
|
||||
"Point3d {x; y; z}",
|
||||
"",
|
||||
"norm self = self::x**2 + self::y**2 + self::z**2",
|
||||
"",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue