mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 10:49:54 +00:00
feat: type narrowing with hasattr
This commit is contained in:
parent
ce5eafca9b
commit
d7d422dfdc
2 changed files with 30 additions and 2 deletions
|
@ -40,7 +40,7 @@ use crate::ty::free::Constraint;
|
|||
use crate::ty::typaram::TyParam;
|
||||
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||
use crate::ty::{
|
||||
CastTarget, GuardType, HasType, ParamTy, Predicate, SubrType, Type, VisibilityModifier,
|
||||
CastTarget, Field, GuardType, HasType, ParamTy, Predicate, SubrType, Type, VisibilityModifier,
|
||||
};
|
||||
|
||||
use crate::context::{
|
||||
|
@ -994,7 +994,27 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
|||
&call.args.nth_or_key(0, "object"),
|
||||
&call.args.nth_or_key(1, "classinfo"),
|
||||
) {
|
||||
self.get_bin_guard_type(ident.name.token(), lhs, rhs)
|
||||
match &ident.inspect()[..] {
|
||||
"isinstance" | "issubclass" => {
|
||||
self.get_bin_guard_type(ident.name.token(), lhs, rhs)
|
||||
}
|
||||
"hasattr" => {
|
||||
let ast::Expr::Literal(lit) = rhs else {
|
||||
return None;
|
||||
};
|
||||
if !lit.is(TokenKind::StrLit) {
|
||||
return None;
|
||||
}
|
||||
let name = lit.token.content.trim_matches('\"');
|
||||
let target = self.expr_to_cast_target(lhs);
|
||||
let rec = dict! {
|
||||
Field::new(VisibilityModifier::Public, Str::rc(name)) => Type::Obj,
|
||||
};
|
||||
let to = Type::Record(rec).structuralize();
|
||||
Some(guard(self.module.context.name.clone(), target, to))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -62,3 +62,11 @@ int_or_strs(rec: { .x = Int } or { .x = Str; .y = Str }): Str =
|
|||
do: rec.y
|
||||
do: str rec.x
|
||||
assert int_or_strs({.x = 1}) == "1"
|
||||
|
||||
C = Class { .foo = Int; .bar = Str }
|
||||
D = Class { .baz = Str }
|
||||
bar x: C or D =
|
||||
if hasattr(x, "foo"):
|
||||
do: x.bar
|
||||
do: "?"
|
||||
assert bar(C.new { .foo = 1; .bar = "bar" }) == "bar"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue