mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-02 21:44:34 +00:00
feat: add restricted visibility syntax
This commit is contained in:
parent
309bb06db8
commit
d92f5284c8
44 changed files with 3803 additions and 2358 deletions
|
@ -200,9 +200,9 @@ impl<'a> HIRVisitor<'a> {
|
|||
token: &Token,
|
||||
) -> Option<&Expr> {
|
||||
match acc {
|
||||
Accessor::Ident(ident) => self.return_expr_if_same(expr, ident.name.token(), token),
|
||||
Accessor::Ident(ident) => self.return_expr_if_same(expr, ident.raw.name.token(), token),
|
||||
Accessor::Attr(attr) => self
|
||||
.return_expr_if_same(expr, attr.ident.name.token(), token)
|
||||
.return_expr_if_same(expr, attr.ident.raw.name.token(), token)
|
||||
.or_else(|| self.get_expr(&attr.obj, token)),
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ impl<'a> HIRVisitor<'a> {
|
|||
.or_else(|| {
|
||||
call.attr_name
|
||||
.as_ref()
|
||||
.and_then(|attr| self.return_expr_if_same(expr, attr.name.token(), token))
|
||||
.and_then(|attr| self.return_expr_if_same(expr, attr.raw.name.token(), token))
|
||||
})
|
||||
.or_else(|| self.get_expr(&call.obj, token))
|
||||
.or_else(|| self.get_expr_from_args(&call.args, token))
|
||||
|
@ -266,7 +266,7 @@ impl<'a> HIRVisitor<'a> {
|
|||
def: &'e Def,
|
||||
token: &Token,
|
||||
) -> Option<&Expr> {
|
||||
self.return_expr_if_same(expr, def.sig.ident().name.token(), token)
|
||||
self.return_expr_if_same(expr, def.sig.ident().raw.name.token(), token)
|
||||
.or_else(|| self.get_expr_from_block(&def.body.block, token))
|
||||
.or_else(|| def.loc().contains(token.loc()).then_some(expr))
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ impl<'a> HIRVisitor<'a> {
|
|||
patch_def: &'e PatchDef,
|
||||
token: &Token,
|
||||
) -> Option<&Expr> {
|
||||
self.return_expr_if_same(expr, patch_def.sig.ident().name.token(), token)
|
||||
self.return_expr_if_same(expr, patch_def.sig.name().token(), token)
|
||||
.or_else(|| self.get_expr(&patch_def.base, token))
|
||||
.or_else(|| self.get_expr_from_block(&patch_def.methods, token))
|
||||
.or_else(|| patch_def.loc().contains(token.loc()).then_some(expr))
|
||||
|
@ -489,10 +489,10 @@ impl<'a> HIRVisitor<'a> {
|
|||
fn get_acc_info(&self, acc: &Accessor, token: &Token) -> Option<VarInfo> {
|
||||
match acc {
|
||||
Accessor::Ident(ident) => {
|
||||
self.return_var_info_if_same(ident, ident.name.token(), token)
|
||||
self.return_var_info_if_same(ident, ident.raw.name.token(), token)
|
||||
}
|
||||
Accessor::Attr(attr) => self
|
||||
.return_var_info_if_same(&attr.ident, attr.ident.name.token(), token)
|
||||
.return_var_info_if_same(&attr.ident, attr.ident.raw.name.token(), token)
|
||||
.or_else(|| self.get_expr_info(&attr.obj, token)),
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +504,7 @@ impl<'a> HIRVisitor<'a> {
|
|||
|
||||
fn get_call_info(&self, call: &Call, token: &Token) -> Option<VarInfo> {
|
||||
if let Some(attr) = &call.attr_name {
|
||||
if let Some(t) = self.return_var_info_if_same(attr, attr.name.token(), token) {
|
||||
if let Some(t) = self.return_var_info_if_same(attr, attr.raw.name.token(), token) {
|
||||
return Some(t);
|
||||
}
|
||||
}
|
||||
|
@ -534,10 +534,10 @@ impl<'a> HIRVisitor<'a> {
|
|||
fn get_sig_info(&self, sig: &Signature, token: &Token) -> Option<VarInfo> {
|
||||
match sig {
|
||||
Signature::Var(var) => {
|
||||
self.return_var_info_if_same(&var.ident, var.ident.name.token(), token)
|
||||
self.return_var_info_if_same(&var.ident, var.name().token(), token)
|
||||
}
|
||||
Signature::Subr(subr) => self
|
||||
.return_var_info_if_same(&subr.ident, subr.ident.name.token(), token)
|
||||
.return_var_info_if_same(&subr.ident, subr.name().token(), token)
|
||||
.or_else(|| self.get_params_info(&subr.params, token)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -526,7 +526,7 @@ impl<Checker: BuildRunnable> Server<Checker> {
|
|||
ctxs.extend(type_ctxs);
|
||||
if let Ok(singular_ctx) = module
|
||||
.context
|
||||
.get_singular_ctx_by_hir_expr(expr, &"".into())
|
||||
.get_singular_ctx_by_hir_expr(expr, &module.context)
|
||||
{
|
||||
ctxs.push(singular_ctx);
|
||||
}
|
||||
|
|
|
@ -40,14 +40,17 @@ pub fn levenshtein(a: &str, b: &str, limit: usize) -> Option<usize> {
|
|||
(dcol[m] <= limit).then_some(dcol[m])
|
||||
}
|
||||
|
||||
pub fn get_similar_name<'a, I: Iterator<Item = &'a str> + Clone>(
|
||||
pub fn get_similar_name<'a, S: ?Sized, I: Iterator<Item = &'a S> + Clone>(
|
||||
candidates: I,
|
||||
name: &str,
|
||||
) -> Option<&'a str> {
|
||||
let limit = (name.len() as f64).sqrt() as usize;
|
||||
) -> Option<&'a S>
|
||||
where
|
||||
S: std::borrow::Borrow<str>,
|
||||
{
|
||||
let limit = (name.len() as f64).sqrt().round() as usize;
|
||||
let most_similar_name =
|
||||
candidates.min_by_key(|v| levenshtein(v, name, limit).unwrap_or(usize::MAX))?;
|
||||
let dist = levenshtein(most_similar_name, name, limit);
|
||||
candidates.min_by_key(|v| levenshtein(v.borrow(), name, limit).unwrap_or(usize::MAX))?;
|
||||
let dist = levenshtein(most_similar_name.borrow(), name, limit);
|
||||
if dist.is_none() || dist.unwrap() >= limit {
|
||||
None
|
||||
} else {
|
||||
|
@ -55,6 +58,24 @@ pub fn get_similar_name<'a, I: Iterator<Item = &'a str> + Clone>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_similar_name_and_some<'a, S: ?Sized, T, I: Iterator<Item = (&'a T, &'a S)> + Clone>(
|
||||
candidates: I,
|
||||
name: &str,
|
||||
) -> Option<(&'a T, &'a S)>
|
||||
where
|
||||
S: std::borrow::Borrow<str>,
|
||||
{
|
||||
let limit = (name.len() as f64).sqrt().round() as usize;
|
||||
let most_similar_name_and_some = candidates
|
||||
.min_by_key(|(_, v)| levenshtein(v.borrow(), name, limit).unwrap_or(usize::MAX))?;
|
||||
let dist = levenshtein(most_similar_name_and_some.1.borrow(), name, limit);
|
||||
if dist.is_none() || dist.unwrap() >= limit {
|
||||
None
|
||||
} else {
|
||||
Some(most_similar_name_and_some)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::levenshtein::get_similar_name;
|
||||
|
|
|
@ -31,9 +31,9 @@ pub mod stdin;
|
|||
pub mod str;
|
||||
pub mod style;
|
||||
pub mod traits;
|
||||
pub mod triple;
|
||||
pub mod tsort;
|
||||
pub mod tty;
|
||||
pub mod vis;
|
||||
|
||||
use crate::set::Set;
|
||||
pub use crate::str::Str;
|
||||
|
|
|
@ -199,6 +199,30 @@ impl Str {
|
|||
ret
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// use erg_common::str::Str;
|
||||
/// let s = Str::rc("a.b.c");
|
||||
/// assert_eq!(s.rpartition_with(&[".", "/"]), ("a.b", "c"));
|
||||
/// let s = Str::rc("a::b.c");
|
||||
/// assert_eq!(s.rpartition_with(&["/", "::"]), ("a", "b.c"));
|
||||
/// ```
|
||||
pub fn rpartition_with(&self, seps: &[&str]) -> (&str, &str) {
|
||||
let mut i = self.len();
|
||||
while i > 0 {
|
||||
for sep in seps {
|
||||
if self[i..].starts_with(sep) {
|
||||
return (&self[..i], &self[i + sep.len()..]);
|
||||
}
|
||||
}
|
||||
i -= 1;
|
||||
}
|
||||
(&self[..], "")
|
||||
}
|
||||
|
||||
pub fn reversed(&self) -> Str {
|
||||
Str::rc(&self.chars().rev().collect::<String>())
|
||||
}
|
||||
|
||||
pub fn multi_replace(&self, paths: &[(&str, &str)]) -> Self {
|
||||
let mut self_ = self.to_string();
|
||||
for (from, to) in paths {
|
||||
|
@ -237,11 +261,6 @@ impl Str {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::dict;
|
||||
// use crate::dict::Dict;
|
||||
|
||||
use crate::vis::Field;
|
||||
|
||||
#[test]
|
||||
fn test_split_with() {
|
||||
assert_eq!(
|
||||
|
@ -261,17 +280,4 @@ mod tests {
|
|||
vec!["aa", "bb", "ff"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_std_key() {
|
||||
let dict = dict! {Str::ever("a") => 1, Str::rc("b") => 2};
|
||||
assert_eq!(dict.get("a"), Some(&1));
|
||||
assert_eq!(dict.get("b"), Some(&2));
|
||||
assert_eq!(dict.get(&Str::ever("b")), Some(&2));
|
||||
assert_eq!(dict.get(&Str::rc("b")), Some(&2));
|
||||
|
||||
let dict = dict! {Field::private(Str::ever("a")) => 1, Field::public(Str::ever("b")) => 2};
|
||||
assert_eq!(dict.get("a"), Some(&1));
|
||||
assert_eq!(dict.get("b"), Some(&2));
|
||||
}
|
||||
}
|
||||
|
|
82
crates/erg_common/triple.rs
Normal file
82
crates/erg_common/triple.rs
Normal file
|
@ -0,0 +1,82 @@
|
|||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Triple<T, E> {
|
||||
Ok(T),
|
||||
Err(E),
|
||||
None,
|
||||
}
|
||||
|
||||
impl<T, E> Triple<T, E> {
|
||||
pub fn none_then(self, err: E) -> Result<T, E> {
|
||||
match self {
|
||||
Triple::None => Err(err),
|
||||
Triple::Ok(ok) => Ok(ok),
|
||||
Triple::Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn none_or_result(self, f: impl FnOnce() -> E) -> Result<T, E> {
|
||||
match self {
|
||||
Triple::None => Err(f()),
|
||||
Triple::Ok(ok) => Ok(ok),
|
||||
Triple::Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn none_or_else(self, f: impl FnOnce() -> Triple<T, E>) -> Triple<T, E> {
|
||||
match self {
|
||||
Triple::None => f(),
|
||||
Triple::Ok(ok) => Triple::Ok(ok),
|
||||
Triple::Err(err) => Triple::Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_to_result(self) -> Result<T, E> {
|
||||
match self {
|
||||
Triple::None => panic!("unwrapping Triple::None"),
|
||||
Triple::Ok(ok) => Ok(ok),
|
||||
Triple::Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ok(self) -> Option<T> {
|
||||
match self {
|
||||
Triple::None => None,
|
||||
Triple::Ok(ok) => Some(ok),
|
||||
Triple::Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn or_else(self, f: impl FnOnce() -> Result<T, E>) -> Result<T, E> {
|
||||
match self {
|
||||
Triple::None => f(),
|
||||
Triple::Ok(ok) => Ok(ok),
|
||||
Triple::Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_or(self, default: T) -> T {
|
||||
match self {
|
||||
Triple::None => default,
|
||||
Triple::Ok(ok) => ok,
|
||||
Triple::Err(_) => default,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_err(self) -> E {
|
||||
match self {
|
||||
Triple::None => panic!("unwrapping Triple::None"),
|
||||
Triple::Ok(_) => panic!("unwrapping Triple::Ok"),
|
||||
Triple::Err(err) => err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E: std::error::Error> Triple<T, E> {
|
||||
pub fn unwrap(self) -> T {
|
||||
match self {
|
||||
Triple::None => panic!("unwrapping Triple::None"),
|
||||
Triple::Ok(ok) => ok,
|
||||
Triple::Err(err) => panic!("unwrapping Triple::Err({err})"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
use std::borrow::Borrow;
|
||||
use std::fmt;
|
||||
|
||||
use crate::Str;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(u8)]
|
||||
pub enum Visibility {
|
||||
Private,
|
||||
Public,
|
||||
}
|
||||
|
||||
impl Visibility {
|
||||
pub const fn is_public(&self) -> bool {
|
||||
matches!(self, Self::Public)
|
||||
}
|
||||
pub const fn is_private(&self) -> bool {
|
||||
matches!(self, Self::Private)
|
||||
}
|
||||
}
|
||||
|
||||
/// same structure as `Identifier`, but only for Record fields.
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
pub struct Field {
|
||||
pub vis: Visibility,
|
||||
pub symbol: Str,
|
||||
}
|
||||
|
||||
impl PartialEq for Field {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.symbol == other.symbol
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for Field {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.symbol.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Field {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.vis.is_public() {
|
||||
write!(f, ".{}", self.symbol)
|
||||
} else {
|
||||
write!(f, "::{}", self.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<str> for Field {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &str {
|
||||
&self.symbol[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<Str> for Field {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &Str {
|
||||
&self.symbol
|
||||
}
|
||||
}
|
||||
|
||||
impl Field {
|
||||
pub const fn new(vis: Visibility, symbol: Str) -> Self {
|
||||
Field { vis, symbol }
|
||||
}
|
||||
|
||||
pub const fn private(symbol: Str) -> Self {
|
||||
Field::new(Visibility::Private, symbol)
|
||||
}
|
||||
|
||||
pub const fn public(symbol: Str) -> Self {
|
||||
Field::new(Visibility::Public, symbol)
|
||||
}
|
||||
|
||||
pub fn is_const(&self) -> bool {
|
||||
self.symbol.starts_with(char::is_uppercase)
|
||||
}
|
||||
}
|
|
@ -17,11 +17,11 @@ use erg_common::opcode311::{BinOpCode, Opcode311};
|
|||
use erg_common::option_enum_unwrap;
|
||||
use erg_common::python_util::{env_python_version, PythonVersion};
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
use erg_common::vis::Visibility;
|
||||
use erg_common::Str;
|
||||
use erg_common::{
|
||||
debug_power_assert, enum_unwrap, fn_name, fn_name_full, impl_stream, log, switch_unreachable,
|
||||
};
|
||||
use erg_parser::ast::VisModifierSpec;
|
||||
use erg_parser::ast::{DefId, DefKind};
|
||||
use CommonOpcode::*;
|
||||
|
||||
|
@ -38,7 +38,7 @@ use crate::hir::{
|
|||
SubrSignature, Tuple, UnaryOp, VarSignature, HIR,
|
||||
};
|
||||
use crate::ty::value::ValueObj;
|
||||
use crate::ty::{HasType, Type, TypeCode, TypePair};
|
||||
use crate::ty::{HasType, Type, TypeCode, TypePair, VisibilityModifier};
|
||||
use crate::varinfo::VarInfo;
|
||||
use erg_common::fresh::fresh_varname;
|
||||
use AccessKind::*;
|
||||
|
@ -70,7 +70,7 @@ fn debind(ident: &Identifier) -> Option<Str> {
|
|||
}
|
||||
}
|
||||
|
||||
fn escape_name(name: &str, vis: Visibility) -> Str {
|
||||
fn escape_name(name: &str, vis: &VisibilityModifier) -> Str {
|
||||
let name = name.replace('!', "__erg_proc__");
|
||||
let name = name.replace('$', "__erg_shared__");
|
||||
if vis.is_private() {
|
||||
|
@ -908,7 +908,7 @@ impl PyCodeGenerator {
|
|||
if s == "_" {
|
||||
format!("_{i}")
|
||||
} else {
|
||||
escape_name(s, Visibility::Private).to_string()
|
||||
escape_name(s, &VisibilityModifier::Private).to_string()
|
||||
}
|
||||
})
|
||||
.map(|s| self.get_cached(&s))
|
||||
|
@ -930,11 +930,11 @@ impl PyCodeGenerator {
|
|||
// Since Erg does not allow the coexistence of private and public variables with the same name, there is no problem in this trick.
|
||||
let is_record = a.obj.ref_t().is_record();
|
||||
if is_record {
|
||||
a.ident.dot = Some(DOT);
|
||||
a.ident.raw.vis = VisModifierSpec::Public(DOT);
|
||||
}
|
||||
if let Some(varname) = debind(&a.ident) {
|
||||
a.ident.dot = None;
|
||||
a.ident.name = VarName::from_str(varname);
|
||||
a.ident.raw.vis = VisModifierSpec::Private;
|
||||
a.ident.raw.name = VarName::from_str(varname);
|
||||
self.emit_load_name_instr(a.ident);
|
||||
} else {
|
||||
self.emit_expr(*a.obj);
|
||||
|
@ -1153,9 +1153,9 @@ impl PyCodeGenerator {
|
|||
self.emit_load_const(code);
|
||||
if self.py_version.minor < Some(11) {
|
||||
if let Some(class) = class_name {
|
||||
self.emit_load_const(Str::from(format!("{class}.{}", ident.name.inspect())));
|
||||
self.emit_load_const(Str::from(format!("{class}.{}", ident.inspect())));
|
||||
} else {
|
||||
self.emit_load_const(ident.name.inspect().clone());
|
||||
self.emit_load_const(ident.inspect().clone());
|
||||
}
|
||||
} else {
|
||||
self.stack_inc();
|
||||
|
@ -1213,8 +1213,8 @@ impl PyCodeGenerator {
|
|||
patch_def.sig.ident().to_string_notype(),
|
||||
def.sig.ident().to_string_notype()
|
||||
);
|
||||
def.sig.ident_mut().name = VarName::from_str(Str::from(name));
|
||||
def.sig.ident_mut().dot = None;
|
||||
def.sig.ident_mut().raw.name = VarName::from_str(Str::from(name));
|
||||
def.sig.ident_mut().raw.vis = VisModifierSpec::Private;
|
||||
self.emit_def(def);
|
||||
}
|
||||
}
|
||||
|
@ -1925,7 +1925,8 @@ impl PyCodeGenerator {
|
|||
}
|
||||
match param.raw.pat {
|
||||
ParamPattern::VarName(name) => {
|
||||
let ident = Identifier::bare(None, name);
|
||||
let ident = erg_parser::ast::Identifier::private_from_varname(name);
|
||||
let ident = Identifier::bare(ident);
|
||||
self.emit_store_instr(ident, AccessKind::Name);
|
||||
}
|
||||
ParamPattern::Discard(_) => {
|
||||
|
@ -2190,7 +2191,7 @@ impl PyCodeGenerator {
|
|||
let kw = if is_py_api {
|
||||
arg.keyword.content
|
||||
} else {
|
||||
escape_name(&arg.keyword.content, Visibility::Private)
|
||||
escape_name(&arg.keyword.content, &VisibilityModifier::Private)
|
||||
};
|
||||
kws.push(ValueObj::Str(kw));
|
||||
self.emit_expr(arg.expr);
|
||||
|
@ -2301,7 +2302,7 @@ impl PyCodeGenerator {
|
|||
mut args: Args,
|
||||
) {
|
||||
log!(info "entered {}", fn_name!());
|
||||
method_name.dot = None;
|
||||
method_name.raw.vis = VisModifierSpec::Private;
|
||||
method_name.vi.py_name = Some(func_name);
|
||||
self.emit_push_null();
|
||||
self.emit_load_name_instr(method_name);
|
||||
|
@ -2785,6 +2786,7 @@ impl PyCodeGenerator {
|
|||
let vi = VarInfo::nd_parameter(
|
||||
__new__.return_t().unwrap().clone(),
|
||||
ident.vi.def_loc.clone(),
|
||||
"?".into(),
|
||||
);
|
||||
let raw =
|
||||
erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(self_param), None);
|
||||
|
@ -2797,7 +2799,11 @@ impl PyCodeGenerator {
|
|||
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line);
|
||||
let raw =
|
||||
erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
|
||||
let vi = VarInfo::nd_parameter(new_first_param.typ().clone(), ident.vi.def_loc.clone());
|
||||
let vi = VarInfo::nd_parameter(
|
||||
new_first_param.typ().clone(),
|
||||
ident.vi.def_loc.clone(),
|
||||
"?".into(),
|
||||
);
|
||||
let param = NonDefaultParamSignature::new(raw, vi, None);
|
||||
let params = Params::new(vec![self_param, param], None, vec![], None);
|
||||
(param_name, params)
|
||||
|
@ -2818,20 +2824,19 @@ impl PyCodeGenerator {
|
|||
for field in rec.keys() {
|
||||
let obj =
|
||||
Expr::Accessor(Accessor::private_with_line(Str::from(¶m_name), line));
|
||||
let expr = obj.attr_expr(Identifier::bare(
|
||||
Some(DOT),
|
||||
VarName::from_str(field.symbol.clone()),
|
||||
));
|
||||
let ident = erg_parser::ast::Identifier::public(field.symbol.clone());
|
||||
let expr = obj.attr_expr(Identifier::bare(ident));
|
||||
let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line));
|
||||
let dot = if field.vis.is_private() {
|
||||
None
|
||||
VisModifierSpec::Private
|
||||
} else {
|
||||
Some(DOT)
|
||||
VisModifierSpec::Public(DOT)
|
||||
};
|
||||
let attr = obj.attr(Identifier::bare(
|
||||
let attr = erg_parser::ast::Identifier::new(
|
||||
dot,
|
||||
VarName::from_str(field.symbol.clone()),
|
||||
));
|
||||
);
|
||||
let attr = obj.attr(Identifier::bare(attr));
|
||||
let redef = ReDef::new(attr, Block::new(vec![expr]));
|
||||
attrs.push(Expr::ReDef(redef));
|
||||
}
|
||||
|
@ -2865,8 +2870,7 @@ impl PyCodeGenerator {
|
|||
let line = sig.ln_begin().unwrap();
|
||||
let mut ident = Identifier::public_with_line(DOT, Str::ever("new"), line);
|
||||
let class = Expr::Accessor(Accessor::Ident(class_ident.clone()));
|
||||
let mut new_ident =
|
||||
Identifier::bare(None, VarName::from_str_and_line(Str::ever("__new__"), line));
|
||||
let mut new_ident = Identifier::private_with_line(Str::ever("__new__"), line);
|
||||
new_ident.vi.py_name = Some(Str::ever("__call__"));
|
||||
let class_new = class.attr_expr(new_ident);
|
||||
ident.vi.t = __new__;
|
||||
|
@ -2876,7 +2880,11 @@ impl PyCodeGenerator {
|
|||
.map(|s| s.to_string())
|
||||
.unwrap_or_else(fresh_varname);
|
||||
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line);
|
||||
let vi = VarInfo::nd_parameter(new_first_param.typ().clone(), ident.vi.def_loc.clone());
|
||||
let vi = VarInfo::nd_parameter(
|
||||
new_first_param.typ().clone(),
|
||||
ident.vi.def_loc.clone(),
|
||||
"?".into(),
|
||||
);
|
||||
let raw =
|
||||
erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
|
||||
let param = NonDefaultParamSignature::new(raw, vi, None);
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
//! provides type-comparison
|
||||
use std::option::Option; // conflicting to Type::Option
|
||||
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::error::MultiErrorDisplay;
|
||||
use erg_common::style::colors::DEBUG_ERROR;
|
||||
use erg_common::traits::StructuralEq;
|
||||
use erg_common::{assume_unreachable, log};
|
||||
|
||||
use crate::ty::constructors::{and, not, or, poly};
|
||||
use crate::ty::free::{Constraint, FreeKind};
|
||||
use crate::ty::typaram::{OpKind, TyParam, TyParamOrdering};
|
||||
use crate::ty::value::ValueObj;
|
||||
use crate::ty::value::ValueObj::Inf;
|
||||
use crate::ty::{Predicate, RefinementType, SubrKind, SubrType, Type};
|
||||
use crate::ty::{Field, Predicate, RefinementType, SubrKind, SubrType, Type};
|
||||
use Predicate as Pred;
|
||||
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::vis::Field;
|
||||
use erg_common::{assume_unreachable, log};
|
||||
use TyParamOrdering::*;
|
||||
use Type::*;
|
||||
|
||||
|
@ -705,7 +704,12 @@ impl Context {
|
|||
.unwrap_or_else(|| panic!("{other} is not found"));
|
||||
ctx.type_dir()
|
||||
.into_iter()
|
||||
.map(|(name, vi)| (Field::new(vi.vis, name.inspect().clone()), vi.t.clone()))
|
||||
.map(|(name, vi)| {
|
||||
(
|
||||
Field::new(vi.vis.modifier.clone(), name.inspect().clone()),
|
||||
vi.t.clone(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ use erg_common::log;
|
|||
use erg_common::set::Set;
|
||||
use erg_common::shared::Shared;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
use erg_common::vis::Field;
|
||||
use erg_common::{dict, fn_name, option_enum_unwrap, set};
|
||||
use erg_common::{enum_unwrap, fmt_vec};
|
||||
use erg_common::{RcArray, Str};
|
||||
|
@ -27,7 +26,7 @@ use crate::ty::typaram::{OpKind, TyParam};
|
|||
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||
use crate::ty::{ConstSubr, HasType, Predicate, SubrKind, Type, UserConstSubr, ValueArgs};
|
||||
|
||||
use crate::context::instantiate::ParamKind;
|
||||
use crate::context::instantiate_spec::ParamKind;
|
||||
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode};
|
||||
use crate::error::{EvalError, EvalErrors, EvalResult, SingleEvalResult};
|
||||
|
||||
|
@ -166,7 +165,10 @@ impl Context {
|
|||
}
|
||||
|
||||
fn eval_attr(&self, obj: ValueObj, ident: &Identifier) -> SingleEvalResult<ValueObj> {
|
||||
if let Some(val) = obj.try_get_attr(&Field::from(ident)) {
|
||||
let field = self
|
||||
.instantiate_field(ident)
|
||||
.map_err(|mut errs| errs.remove(0))?;
|
||||
if let Some(val) = obj.try_get_attr(&field) {
|
||||
return Ok(val);
|
||||
}
|
||||
if let ValueObj::Type(t) = &obj {
|
||||
|
@ -301,7 +303,7 @@ impl Context {
|
|||
fn eval_const_def(&mut self, def: &Def) -> EvalResult<ValueObj> {
|
||||
if def.is_const() {
|
||||
let __name__ = def.sig.ident().unwrap().inspect();
|
||||
let vis = def.sig.vis();
|
||||
let vis = self.instantiate_vis_modifier(def.sig.vis())?;
|
||||
let tv_cache = match &def.sig {
|
||||
Signature::Subr(subr) => {
|
||||
let ty_cache =
|
||||
|
@ -430,7 +432,7 @@ impl Context {
|
|||
let elem = record_ctx.eval_const_block(&attr.body.block)?;
|
||||
let ident = match &attr.sig {
|
||||
Signature::Var(var) => match &var.pat {
|
||||
VarPattern::Ident(ident) => Field::new(ident.vis(), ident.inspect().clone()),
|
||||
VarPattern::Ident(ident) => self.instantiate_field(ident)?,
|
||||
other => {
|
||||
return feature_error!(self, other.loc(), &format!("record field: {other}"))
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,25 +1,23 @@
|
|||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::vis::{Field, Visibility};
|
||||
|
||||
use crate::ty::constructors::*;
|
||||
use crate::ty::typaram::TyParam;
|
||||
use crate::ty::value::ValueObj;
|
||||
use crate::ty::Type;
|
||||
use crate::ty::{Field, Type, Visibility};
|
||||
use Type::*;
|
||||
|
||||
use crate::context::initialize::*;
|
||||
use crate::context::Context;
|
||||
use crate::varinfo::Mutability;
|
||||
use Mutability::*;
|
||||
use Visibility::*;
|
||||
|
||||
impl Context {
|
||||
pub(super) fn init_builtin_funcs(&mut self) {
|
||||
let vis = if cfg!(feature = "py_compatible") {
|
||||
Public
|
||||
Visibility::BUILTIN_PUBLIC
|
||||
} else {
|
||||
Private
|
||||
Visibility::BUILTIN_PRIVATE
|
||||
};
|
||||
let T = mono_q(TY_T, instanceof(Type));
|
||||
let U = mono_q(TY_U, instanceof(Type));
|
||||
|
@ -222,96 +220,144 @@ impl Context {
|
|||
self.register_py_builtin(FUNC_ANY, t_any, Some(FUNC_ANY), 33);
|
||||
self.register_py_builtin(FUNC_ASCII, t_ascii, Some(FUNC_ASCII), 53);
|
||||
// Leave as `Const`, as it may negatively affect assert casting.
|
||||
self.register_builtin_erg_impl(FUNC_ASSERT, t_assert, Const, vis);
|
||||
self.register_builtin_py_impl(FUNC_BIN, t_bin, Immutable, vis, Some(FUNC_BIN));
|
||||
self.register_builtin_py_impl(FUNC_BYTES, t_bytes, Immutable, vis, Some(FUNC_BYTES));
|
||||
self.register_builtin_py_impl(FUNC_CHR, t_chr, Immutable, vis, Some(FUNC_CHR));
|
||||
self.register_builtin_py_impl(FUNC_CLASSOF, t_classof, Immutable, vis, Some(FUNC_TYPE));
|
||||
self.register_builtin_py_impl(FUNC_COMPILE, t_compile, Immutable, vis, Some(FUNC_COMPILE));
|
||||
self.register_builtin_erg_impl(KW_COND, t_cond, Immutable, vis);
|
||||
self.register_builtin_erg_impl(FUNC_ASSERT, t_assert, Const, vis.clone());
|
||||
self.register_builtin_py_impl(FUNC_BIN, t_bin, Immutable, vis.clone(), Some(FUNC_BIN));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_BYTES,
|
||||
t_bytes,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_BYTES),
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_CHR, t_chr, Immutable, vis.clone(), Some(FUNC_CHR));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_CLASSOF,
|
||||
t_classof,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_TYPE),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_COMPILE,
|
||||
t_compile,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_COMPILE),
|
||||
);
|
||||
self.register_builtin_erg_impl(KW_COND, t_cond, Immutable, vis.clone());
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_ENUMERATE,
|
||||
t_enumerate,
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNC_ENUMERATE),
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_EXIT, t_exit, Immutable, vis, Some(FUNC_EXIT));
|
||||
self.register_builtin_py_impl(FUNC_EXIT, t_exit, Immutable, vis.clone(), Some(FUNC_EXIT));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_ISINSTANCE,
|
||||
t_isinstance,
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNC_ISINSTANCE),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_ISSUBCLASS,
|
||||
t_issubclass,
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNC_ISSUBCLASS),
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_ITER, t_iter, Immutable, vis, Some(FUNC_ITER));
|
||||
self.register_builtin_py_impl(FUNC_LEN, t_len, Immutable, vis, Some(FUNC_LEN));
|
||||
self.register_builtin_py_impl(FUNC_MAP, t_map, Immutable, vis, Some(FUNC_MAP));
|
||||
self.register_builtin_py_impl(FUNC_MAX, t_max, Immutable, vis, Some(FUNC_MAX));
|
||||
self.register_builtin_py_impl(FUNC_MIN, t_min, Immutable, vis, Some(FUNC_MIN));
|
||||
self.register_builtin_py_impl(FUNC_NOT, t_not, Immutable, vis, None); // `not` is not a function in Python
|
||||
self.register_builtin_py_impl(FUNC_OCT, t_oct, Immutable, vis, Some(FUNC_OCT));
|
||||
self.register_builtin_py_impl(FUNC_ORD, t_ord, Immutable, vis, Some(FUNC_ORD));
|
||||
self.register_builtin_py_impl(FUNC_POW, t_pow, Immutable, vis, Some(FUNC_POW));
|
||||
self.register_builtin_py_impl(FUNC_ITER, t_iter, Immutable, vis.clone(), Some(FUNC_ITER));
|
||||
self.register_builtin_py_impl(FUNC_LEN, t_len, Immutable, vis.clone(), Some(FUNC_LEN));
|
||||
self.register_builtin_py_impl(FUNC_MAP, t_map, Immutable, vis.clone(), Some(FUNC_MAP));
|
||||
self.register_builtin_py_impl(FUNC_MAX, t_max, Immutable, vis.clone(), Some(FUNC_MAX));
|
||||
self.register_builtin_py_impl(FUNC_MIN, t_min, Immutable, vis.clone(), Some(FUNC_MIN));
|
||||
self.register_builtin_py_impl(FUNC_NOT, t_not, Immutable, vis.clone(), None); // `not` is not a function in Python
|
||||
self.register_builtin_py_impl(FUNC_OCT, t_oct, Immutable, vis.clone(), Some(FUNC_OCT));
|
||||
self.register_builtin_py_impl(FUNC_ORD, t_ord, Immutable, vis.clone(), Some(FUNC_ORD));
|
||||
self.register_builtin_py_impl(FUNC_POW, t_pow, Immutable, vis.clone(), Some(FUNC_POW));
|
||||
self.register_builtin_py_impl(
|
||||
PYIMPORT,
|
||||
t_pyimport.clone(),
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNDAMENTAL_IMPORT),
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_QUIT, t_quit, Immutable, vis, Some(FUNC_QUIT));
|
||||
self.register_builtin_py_impl(FUNC_REPR, t_repr, Immutable, vis, Some(FUNC_REPR));
|
||||
self.register_builtin_py_impl(FUNC_QUIT, t_quit, Immutable, vis.clone(), Some(FUNC_QUIT));
|
||||
self.register_builtin_py_impl(FUNC_REPR, t_repr, Immutable, vis.clone(), Some(FUNC_REPR));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_REVERSED,
|
||||
t_reversed,
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNC_REVERSED),
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_ROUND, t_round, Immutable, vis, Some(FUNC_ROUND));
|
||||
self.register_builtin_py_impl(FUNC_SORTED, t_sorted, Immutable, vis, Some(FUNC_SORTED));
|
||||
self.register_builtin_py_impl(FUNC_STR, t_str, Immutable, vis, Some(FUNC_STR__));
|
||||
self.register_builtin_py_impl(FUNC_SUM, t_sum, Immutable, vis, Some(FUNC_SUM));
|
||||
self.register_builtin_py_impl(FUNC_ZIP, t_zip, Immutable, vis, Some(FUNC_ZIP));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_ROUND,
|
||||
t_round,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_ROUND),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_SORTED,
|
||||
t_sorted,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_SORTED),
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_STR, t_str, Immutable, vis.clone(), Some(FUNC_STR__));
|
||||
self.register_builtin_py_impl(FUNC_SUM, t_sum, Immutable, vis.clone(), Some(FUNC_SUM));
|
||||
self.register_builtin_py_impl(FUNC_ZIP, t_zip, Immutable, vis.clone(), Some(FUNC_ZIP));
|
||||
let name = if cfg!(feature = "py_compatible") {
|
||||
FUNC_INT
|
||||
} else {
|
||||
FUNC_INT__
|
||||
};
|
||||
self.register_builtin_py_impl(FUNC_INT, t_int, Immutable, vis, Some(name));
|
||||
self.register_builtin_py_impl(FUNC_INT, t_int, Immutable, vis.clone(), Some(name));
|
||||
if !cfg!(feature = "py_compatible") {
|
||||
self.register_builtin_py_impl(FUNC_IF, t_if, Immutable, vis, Some(FUNC_IF__));
|
||||
self.register_builtin_py_impl(FUNC_IF, t_if, Immutable, vis.clone(), Some(FUNC_IF__));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_DISCARD,
|
||||
t_discard,
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNC_DISCARD__),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_IMPORT,
|
||||
t_import,
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNDAMENTAL_IMPORT),
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_LOG, t_log, Immutable, vis, Some(FUNC_PRINT));
|
||||
self.register_builtin_py_impl(FUNC_NAT, t_nat, Immutable, vis, Some(FUNC_NAT__));
|
||||
self.register_builtin_py_impl(FUNC_PANIC, t_panic, Immutable, vis, Some(FUNC_QUIT));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_LOG,
|
||||
t_log,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_PRINT),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_NAT,
|
||||
t_nat,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_NAT__),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_PANIC,
|
||||
t_panic,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_QUIT),
|
||||
);
|
||||
if cfg!(feature = "debug") {
|
||||
self.register_builtin_py_impl(
|
||||
PY,
|
||||
t_pyimport,
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNDAMENTAL_IMPORT),
|
||||
);
|
||||
}
|
||||
|
@ -319,7 +365,7 @@ impl Context {
|
|||
PYCOMPILE,
|
||||
t_pycompile,
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNC_COMPILE),
|
||||
);
|
||||
// TODO: original implementation
|
||||
|
@ -340,7 +386,13 @@ impl Context {
|
|||
],
|
||||
poly(RANGE, vec![ty_tp(Int)]),
|
||||
);
|
||||
self.register_builtin_py_impl(FUNC_RANGE, t_range, Immutable, vis, Some(FUNC_RANGE));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_RANGE,
|
||||
t_range,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_RANGE),
|
||||
);
|
||||
let t_list = func(
|
||||
vec![],
|
||||
None,
|
||||
|
@ -348,7 +400,13 @@ impl Context {
|
|||
poly(ARRAY, vec![ty_tp(T.clone()), TyParam::erased(Nat)]),
|
||||
)
|
||||
.quantify();
|
||||
self.register_builtin_py_impl(FUNC_LIST, t_list, Immutable, vis, Some(FUNC_LIST));
|
||||
self.register_builtin_py_impl(
|
||||
FUNC_LIST,
|
||||
t_list,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some(FUNC_LIST),
|
||||
);
|
||||
let t_dict = func(
|
||||
vec![],
|
||||
None,
|
||||
|
@ -365,9 +423,9 @@ impl Context {
|
|||
|
||||
pub(super) fn init_builtin_const_funcs(&mut self) {
|
||||
let vis = if cfg!(feature = "py_compatible") {
|
||||
Public
|
||||
Visibility::BUILTIN_PUBLIC
|
||||
} else {
|
||||
Private
|
||||
Visibility::BUILTIN_PRIVATE
|
||||
};
|
||||
let class_t = func(
|
||||
vec![],
|
||||
|
@ -376,7 +434,7 @@ impl Context {
|
|||
ClassType,
|
||||
);
|
||||
let class = ConstSubr::Builtin(BuiltinConstSubr::new(CLASS, class_func, class_t, None));
|
||||
self.register_builtin_const(CLASS, vis, ValueObj::Subr(class));
|
||||
self.register_builtin_const(CLASS, vis.clone(), ValueObj::Subr(class));
|
||||
let inherit_t = func(
|
||||
vec![kw(KW_SUPER, ClassType)],
|
||||
None,
|
||||
|
@ -389,7 +447,7 @@ impl Context {
|
|||
inherit_t,
|
||||
None,
|
||||
));
|
||||
self.register_builtin_const(INHERIT, vis, ValueObj::Subr(inherit));
|
||||
self.register_builtin_const(INHERIT, vis.clone(), ValueObj::Subr(inherit));
|
||||
let trait_t = func(
|
||||
vec![kw(KW_REQUIREMENT, Type)],
|
||||
None,
|
||||
|
@ -397,7 +455,7 @@ impl Context {
|
|||
TraitType,
|
||||
);
|
||||
let trait_ = ConstSubr::Builtin(BuiltinConstSubr::new(TRAIT, trait_func, trait_t, None));
|
||||
self.register_builtin_const(TRAIT, vis, ValueObj::Subr(trait_));
|
||||
self.register_builtin_const(TRAIT, vis.clone(), ValueObj::Subr(trait_));
|
||||
let subsume_t = func(
|
||||
vec![kw(KW_SUPER, TraitType)],
|
||||
None,
|
||||
|
@ -410,14 +468,14 @@ impl Context {
|
|||
subsume_t,
|
||||
None,
|
||||
));
|
||||
self.register_builtin_const(SUBSUME, vis, ValueObj::Subr(subsume));
|
||||
self.register_builtin_const(SUBSUME, vis.clone(), ValueObj::Subr(subsume));
|
||||
let structural = ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||
STRUCTURAL,
|
||||
structural_func,
|
||||
func1(Type, Type),
|
||||
None,
|
||||
));
|
||||
self.register_builtin_const(STRUCTURAL, vis, ValueObj::Subr(structural));
|
||||
self.register_builtin_const(STRUCTURAL, vis.clone(), ValueObj::Subr(structural));
|
||||
// decorators
|
||||
let inheritable_t = func1(ClassType, ClassType);
|
||||
let inheritable = ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||
|
@ -426,10 +484,10 @@ impl Context {
|
|||
inheritable_t,
|
||||
None,
|
||||
));
|
||||
self.register_builtin_const(INHERITABLE, vis, ValueObj::Subr(inheritable));
|
||||
self.register_builtin_const(INHERITABLE, vis.clone(), ValueObj::Subr(inheritable));
|
||||
// TODO: register Del function object
|
||||
let t_del = nd_func(vec![kw(KW_OBJ, Obj)], None, NoneType);
|
||||
self.register_builtin_erg_impl(DEL, t_del, Immutable, vis);
|
||||
self.register_builtin_erg_impl(DEL, t_del, Immutable, vis.clone());
|
||||
let patch_t = func(
|
||||
vec![kw(KW_REQUIREMENT, Type)],
|
||||
None,
|
||||
|
@ -451,65 +509,65 @@ impl Context {
|
|||
proj(L, OUTPUT),
|
||||
)
|
||||
.quantify();
|
||||
self.register_builtin_erg_impl(OP_ADD, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_ADD, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let L = mono_q(TY_L, subtypeof(poly(SUB, params.clone())));
|
||||
let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify();
|
||||
self.register_builtin_erg_impl(OP_SUB, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_SUB, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let L = mono_q(TY_L, subtypeof(poly(MUL, params.clone())));
|
||||
let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify();
|
||||
self.register_builtin_erg_impl(OP_MUL, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_MUL, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let L = mono_q(TY_L, subtypeof(poly(DIV, params.clone())));
|
||||
let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify();
|
||||
self.register_builtin_erg_impl(OP_DIV, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let L = mono_q(TY_L, subtypeof(poly(FLOOR_DIV, params)));
|
||||
let op_t = bin_op(L.clone(), R, proj(L, OUTPUT)).quantify();
|
||||
self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let P = mono_q(TY_P, Constraint::Uninited);
|
||||
let P = mono_q(TY_P, subtypeof(poly(MUL, vec![ty_tp(P)])));
|
||||
let op_t = bin_op(P.clone(), P.clone(), proj(P, POW_OUTPUT)).quantify();
|
||||
// TODO: add bound: M == M.Output
|
||||
self.register_builtin_erg_impl(OP_POW, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_POW, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let M = mono_q(TY_M, Constraint::Uninited);
|
||||
let M = mono_q(TY_M, subtypeof(poly(DIV, vec![ty_tp(M)])));
|
||||
let op_t = bin_op(M.clone(), M.clone(), proj(M, MOD_OUTPUT)).quantify();
|
||||
self.register_builtin_erg_impl(OP_MOD, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_MOD, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = nd_proc(vec![kw(KW_LHS, Obj), kw(KW_RHS, Obj)], None, Bool);
|
||||
self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Private);
|
||||
self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let E = mono_q(TY_E, subtypeof(mono(EQ)));
|
||||
let op_t = bin_op(E.clone(), E, Bool).quantify();
|
||||
self.register_builtin_erg_impl(OP_EQ, op_t.clone(), Const, Private);
|
||||
self.register_builtin_erg_impl(OP_NE, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_EQ, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_impl(OP_NE, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let O = mono_q(TY_O, subtypeof(mono(ORD)));
|
||||
let op_t = bin_op(O.clone(), O.clone(), Bool).quantify();
|
||||
self.register_builtin_erg_impl(OP_LT, op_t.clone(), Const, Private);
|
||||
self.register_builtin_erg_impl(OP_LE, op_t.clone(), Const, Private);
|
||||
self.register_builtin_erg_impl(OP_GT, op_t.clone(), Const, Private);
|
||||
self.register_builtin_erg_impl(OP_GE, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_LT, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_impl(OP_LE, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_impl(OP_GT, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_impl(OP_GE, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let BT = mono_q(TY_BT, subtypeof(or(Bool, Type)));
|
||||
let op_t = bin_op(BT.clone(), BT.clone(), BT).quantify();
|
||||
self.register_builtin_erg_impl(OP_AND, op_t.clone(), Const, Private);
|
||||
self.register_builtin_erg_impl(OP_OR, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_AND, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_impl(OP_OR, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = bin_op(O.clone(), O.clone(), range(O)).quantify();
|
||||
self.register_builtin_erg_decl(OP_RNG, op_t.clone(), Private);
|
||||
self.register_builtin_erg_decl(OP_LORNG, op_t.clone(), Private);
|
||||
self.register_builtin_erg_decl(OP_RORNG, op_t.clone(), Private);
|
||||
self.register_builtin_erg_decl(OP_ORNG, op_t, Private);
|
||||
self.register_builtin_erg_decl(OP_RNG, op_t.clone(), Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_decl(OP_LORNG, op_t.clone(), Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_decl(OP_RORNG, op_t.clone(), Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_decl(OP_ORNG, op_t, Visibility::BUILTIN_PRIVATE);
|
||||
// TODO: use existential type: |T: Type| (T, In(T)) -> Bool
|
||||
let T = mono_q(TY_T, instanceof(Type));
|
||||
let I = mono_q(KW_I, subtypeof(poly(IN, vec![ty_tp(T.clone())])));
|
||||
let op_t = bin_op(I, T, Bool).quantify();
|
||||
self.register_builtin_erg_impl(OP_IN, op_t.clone(), Const, Private);
|
||||
self.register_builtin_erg_impl(OP_NOT_IN, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_IN, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_impl(OP_NOT_IN, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
/* unary */
|
||||
// TODO: +/- Bool would like to be warned
|
||||
let M = mono_q(TY_M, subtypeof(mono(MUTIZABLE)));
|
||||
let op_t = func1(M.clone(), proj(M, MUTABLE_MUT_TYPE)).quantify();
|
||||
self.register_builtin_erg_impl(OP_MUTATE, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_MUTATE, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let N = mono_q(TY_N, subtypeof(mono(NUM)));
|
||||
let op_t = func1(N.clone(), N).quantify();
|
||||
self.register_builtin_erg_decl(OP_POS, op_t.clone(), Private);
|
||||
self.register_builtin_erg_decl(OP_NEG, op_t, Private);
|
||||
self.register_builtin_erg_decl(OP_POS, op_t.clone(), Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_decl(OP_NEG, op_t, Visibility::BUILTIN_PRIVATE);
|
||||
}
|
||||
|
||||
pub(super) fn init_py_builtin_operators(&mut self) {
|
||||
|
@ -525,7 +583,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), O.clone()).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_ADD, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_ADD, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__sub__".into()) => fn1_met(Never, R.clone(), O.clone()) },
|
||||
|
@ -533,7 +591,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), O.clone()).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_SUB, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_SUB, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__mul__".into()) => fn1_met(Never, R.clone(), O.clone()) },
|
||||
|
@ -541,7 +599,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), O.clone()).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_MUL, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_MUL, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__div__".into()) => fn1_met(Never, R.clone(), O.clone()) },
|
||||
|
@ -549,7 +607,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), O.clone()).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_DIV, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__floordiv__".into()) => fn1_met(Never, R.clone(), O.clone()) },
|
||||
|
@ -557,7 +615,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), O.clone()).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__pow__".into()) => fn1_met(Never, R.clone(), O.clone()) },
|
||||
|
@ -565,7 +623,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), O.clone()).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_POW, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_POW, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__mod__".into()) => fn1_met(Never, R.clone(), O.clone()) },
|
||||
|
@ -573,10 +631,10 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), O.clone()).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_MOD, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_MOD, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = nd_proc(vec![kw(KW_LHS, Obj), kw(KW_RHS, Obj)], None, Bool);
|
||||
self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Private);
|
||||
self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
|
||||
self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__eq__".into()) => fn1_met(Never, R.clone(), Bool) },
|
||||
|
@ -584,7 +642,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), Bool).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_EQ, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_EQ, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__ne__".into()) => fn1_met(Never, R.clone(), Bool) },
|
||||
|
@ -592,7 +650,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), Bool).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_NE, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_NE, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__lt__".into()) => fn1_met(Never, R.clone(), Bool) },
|
||||
|
@ -600,7 +658,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), Bool).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_LT, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_LT, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__le__".into()) => fn1_met(Never, R.clone(), Bool) },
|
||||
|
@ -608,7 +666,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), Bool).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_LE, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_LE, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__gt__".into()) => fn1_met(Never, R.clone(), Bool) },
|
||||
|
@ -616,7 +674,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), Bool).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_GT, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_GT, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__ge__".into()) => fn1_met(Never, R.clone(), Bool) },
|
||||
|
@ -624,7 +682,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), Bool).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_GE, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_GE, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__and__".into()) => fn1_met(Never, R.clone(), O.clone()) },
|
||||
|
@ -632,7 +690,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), O.clone()).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_AND, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_AND, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S = Type::from(
|
||||
dict! { Field::public("__or__".into()) => fn1_met(Never, R.clone(), O.clone()) },
|
||||
|
@ -640,7 +698,7 @@ impl Context {
|
|||
.structuralize();
|
||||
bin_op(S, R.clone(), O).quantify()
|
||||
};
|
||||
self.register_builtin_erg_impl(OP_OR, op_t, Const, Private);
|
||||
self.register_builtin_erg_impl(OP_OR, op_t, Const, Visibility::BUILTIN_PRIVATE);
|
||||
/* unary */
|
||||
let op_t = {
|
||||
let S =
|
||||
|
@ -648,13 +706,13 @@ impl Context {
|
|||
.structuralize();
|
||||
func1(S, R.clone()).quantify()
|
||||
};
|
||||
self.register_builtin_erg_decl(OP_POS, op_t, Private);
|
||||
self.register_builtin_erg_decl(OP_POS, op_t, Visibility::BUILTIN_PRIVATE);
|
||||
let op_t = {
|
||||
let S =
|
||||
Type::from(dict! { Field::public("__neg__".into()) => fn0_met(Never, R.clone()) })
|
||||
.structuralize();
|
||||
func1(S, R).quantify()
|
||||
};
|
||||
self.register_builtin_erg_decl(OP_NEG, op_t, Private);
|
||||
self.register_builtin_erg_decl(OP_NEG, op_t, Visibility::BUILTIN_PRIVATE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,28 +18,26 @@ use erg_common::error::Location;
|
|||
use erg_common::fresh::fresh_varname;
|
||||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::vis::Visibility;
|
||||
use erg_common::Str;
|
||||
use erg_common::{set, unique_in_place};
|
||||
|
||||
use erg_parser::ast::VarName;
|
||||
|
||||
use crate::context::initialize::const_func::*;
|
||||
use crate::context::instantiate::ConstTemplate;
|
||||
use crate::context::instantiate_spec::ConstTemplate;
|
||||
use crate::context::{
|
||||
ClassDefType, Context, ContextKind, MethodInfo, ModuleContext, ParamSpec, TraitImpl,
|
||||
};
|
||||
use crate::module::SharedCompilerResource;
|
||||
use crate::ty::free::Constraint;
|
||||
use crate::ty::value::ValueObj;
|
||||
use crate::ty::Type;
|
||||
use crate::ty::{constructors::*, BuiltinConstSubr, ConstSubr, Predicate};
|
||||
use crate::ty::{Type, Visibility};
|
||||
use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind};
|
||||
use Mutability::*;
|
||||
use ParamSpec as PS;
|
||||
use Type::*;
|
||||
use VarKind::*;
|
||||
use Visibility::*;
|
||||
|
||||
const NUM: &str = "Num";
|
||||
|
||||
|
@ -543,7 +541,7 @@ impl Context {
|
|||
);
|
||||
if let Some(_vi) = self.locals.get(&name) {
|
||||
if _vi != &vi {
|
||||
panic!("already registered: {} {name}", self.name);
|
||||
unreachable!("already registered: {} {name}", self.name);
|
||||
}
|
||||
} else {
|
||||
self.locals.insert(name, vi);
|
||||
|
@ -599,9 +597,9 @@ impl Context {
|
|||
VarName::from_static(name)
|
||||
};
|
||||
let vis = if cfg!(feature = "py_compatible") || &self.name[..] != "<builtins>" {
|
||||
Public
|
||||
Visibility::BUILTIN_PUBLIC
|
||||
} else {
|
||||
Private
|
||||
Visibility::BUILTIN_PRIVATE
|
||||
};
|
||||
let muty = Immutable;
|
||||
let loc = Location::range(lineno, 0, lineno, name.inspect().len() as u32);
|
||||
|
@ -859,50 +857,56 @@ impl Context {
|
|||
|
||||
fn init_builtin_consts(&mut self) {
|
||||
let vis = if cfg!(feature = "py_compatible") {
|
||||
Public
|
||||
Visibility::BUILTIN_PUBLIC
|
||||
} else {
|
||||
Private
|
||||
Visibility::BUILTIN_PRIVATE
|
||||
};
|
||||
// TODO: this is not a const, but a special property
|
||||
self.register_builtin_py_impl(
|
||||
FUNDAMENTAL_NAME,
|
||||
Str,
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(FUNDAMENTAL_NAME),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
LICENSE,
|
||||
mono(SITEBUILTINS_PRINTER),
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(LICENSE),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
CREDITS,
|
||||
mono(SITEBUILTINS_PRINTER),
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(CREDITS),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
COPYRIGHT,
|
||||
mono(SITEBUILTINS_PRINTER),
|
||||
Immutable,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(COPYRIGHT),
|
||||
);
|
||||
self.register_builtin_py_impl(
|
||||
NOT_IMPLEMENTED,
|
||||
NotImplementedType,
|
||||
Const,
|
||||
vis,
|
||||
vis.clone(),
|
||||
Some(NOT_IMPLEMENTED),
|
||||
);
|
||||
self.register_builtin_py_impl(ELLIPSIS, Ellipsis, Const, vis, Some(ELLIPSIS));
|
||||
self.register_builtin_py_impl(TRUE, Bool, Const, Private, Some(TRUE));
|
||||
self.register_builtin_py_impl(FALSE, Bool, Const, Private, Some(FALSE));
|
||||
self.register_builtin_py_impl(NONE, NoneType, Const, Private, Some(NONE));
|
||||
self.register_builtin_py_impl(TRUE, Bool, Const, Visibility::BUILTIN_PRIVATE, Some(TRUE));
|
||||
self.register_builtin_py_impl(FALSE, Bool, Const, Visibility::BUILTIN_PRIVATE, Some(FALSE));
|
||||
self.register_builtin_py_impl(
|
||||
NONE,
|
||||
NoneType,
|
||||
Const,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Some(NONE),
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn init_builtins(cfg: ErgConfig, shared: SharedCompilerResource) {
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::vis::Visibility;
|
||||
|
||||
use crate::ty::constructors::*;
|
||||
use crate::ty::typaram::TyParam;
|
||||
use crate::ty::value::ValueObj;
|
||||
use crate::ty::Type;
|
||||
use crate::ty::{Type, Visibility};
|
||||
use Type::*;
|
||||
|
||||
use crate::context::initialize::*;
|
||||
use crate::context::Context;
|
||||
use crate::varinfo::Mutability;
|
||||
use Mutability::*;
|
||||
use Visibility::*;
|
||||
|
||||
impl Context {
|
||||
pub(super) fn init_builtin_patches(&mut self) {
|
||||
|
@ -38,10 +36,10 @@ impl Context {
|
|||
)
|
||||
.quantify();
|
||||
let mut interval_add = Self::builtin_methods(Some(impls), 2);
|
||||
interval_add.register_builtin_erg_impl("__add__", op_t, Const, Public);
|
||||
interval_add.register_builtin_erg_impl("__add__", op_t, Const, Visibility::BUILTIN_PUBLIC);
|
||||
interval_add.register_builtin_const(
|
||||
"Output",
|
||||
Public,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
ValueObj::builtin_t(Type::from(m.clone() + o.clone()..=n.clone() + p.clone())),
|
||||
);
|
||||
interval.register_trait(class.clone(), interval_add);
|
||||
|
@ -53,18 +51,18 @@ impl Context {
|
|||
Type::from(m.clone() - p.clone()..=n.clone() - o.clone()),
|
||||
)
|
||||
.quantify();
|
||||
interval_sub.register_builtin_erg_impl("__sub__", op_t, Const, Public);
|
||||
interval_sub.register_builtin_erg_impl("__sub__", op_t, Const, Visibility::BUILTIN_PUBLIC);
|
||||
interval_sub.register_builtin_const(
|
||||
"Output",
|
||||
Public,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
ValueObj::builtin_t(Type::from(m - p..=n - o)),
|
||||
);
|
||||
interval.register_trait(class, interval_sub);
|
||||
self.register_builtin_patch("Interval", interval, Private, Const);
|
||||
// eq.register_impl("__ne__", op_t, Const, Public);
|
||||
// ord.register_impl("__le__", op_t.clone(), Const, Public);
|
||||
// ord.register_impl("__gt__", op_t.clone(), Const, Public);
|
||||
// ord.register_impl("__ge__", op_t, Const, Public);
|
||||
self.register_builtin_patch("Interval", interval, Visibility::BUILTIN_PRIVATE, Const);
|
||||
// eq.register_impl("__ne__", op_t, Const, Visibility::BUILTIN_PUBLIC);
|
||||
// ord.register_impl("__le__", op_t.clone(), Const, Visibility::BUILTIN_PUBLIC);
|
||||
// ord.register_impl("__gt__", op_t.clone(), Const, Visibility::BUILTIN_PUBLIC);
|
||||
// ord.register_impl("__ge__", op_t, Const, Visibility::BUILTIN_PUBLIC);
|
||||
let E = mono_q("E", subtypeof(mono("Eq")));
|
||||
let base = or(E, NoneType);
|
||||
let impls = mono("Eq");
|
||||
|
@ -73,8 +71,8 @@ impl Context {
|
|||
Self::builtin_poly_glue_patch("OptionEq", base.clone(), impls.clone(), params, 1);
|
||||
let mut option_eq_impl = Self::builtin_methods(Some(impls), 1);
|
||||
let op_t = fn1_met(base.clone(), base.clone(), Bool).quantify();
|
||||
option_eq_impl.register_builtin_erg_impl("__eq__", op_t, Const, Public);
|
||||
option_eq_impl.register_builtin_erg_impl("__eq__", op_t, Const, Visibility::BUILTIN_PUBLIC);
|
||||
option_eq.register_trait(base, option_eq_impl);
|
||||
self.register_builtin_patch("OptionEq", option_eq, Private, Const);
|
||||
self.register_builtin_patch("OptionEq", option_eq, Visibility::BUILTIN_PRIVATE, Const);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::vis::Visibility;
|
||||
|
||||
use crate::ty::constructors::*;
|
||||
use crate::ty::typaram::TyParam;
|
||||
use crate::ty::Type;
|
||||
use crate::ty::{Type, Visibility};
|
||||
use Type::*;
|
||||
|
||||
use crate::context::initialize::*;
|
||||
use crate::context::Context;
|
||||
use crate::varinfo::Mutability;
|
||||
use Mutability::*;
|
||||
use Visibility::*;
|
||||
|
||||
impl Context {
|
||||
pub(super) fn init_builtin_procs(&mut self) {
|
||||
let vis = if cfg!(feature = "py_compatible") {
|
||||
Public
|
||||
Visibility::BUILTIN_PUBLIC
|
||||
} else {
|
||||
Private
|
||||
Visibility::BUILTIN_PRIVATE
|
||||
};
|
||||
let T = mono_q("T", instanceof(Type));
|
||||
let U = mono_q("U", instanceof(Type));
|
||||
|
@ -119,32 +117,38 @@ impl Context {
|
|||
U,
|
||||
)
|
||||
.quantify();
|
||||
self.register_builtin_py_impl("dir!", t_dir, Immutable, vis, Some("dir"));
|
||||
self.register_builtin_py_impl("dir!", t_dir, Immutable, vis.clone(), Some("dir"));
|
||||
self.register_py_builtin("print!", t_print, Some("print"), 81);
|
||||
self.register_builtin_py_impl("id!", t_id, Immutable, vis, Some("id"));
|
||||
self.register_builtin_py_impl("input!", t_input, Immutable, vis, Some("input"));
|
||||
self.register_builtin_py_impl("globals!", t_globals, Immutable, vis, Some("globals"));
|
||||
self.register_builtin_py_impl("locals!", t_locals, Immutable, vis, Some("locals"));
|
||||
self.register_builtin_py_impl("next!", t_next, Immutable, vis, Some("next"));
|
||||
self.register_builtin_py_impl("id!", t_id, Immutable, vis.clone(), Some("id"));
|
||||
self.register_builtin_py_impl("input!", t_input, Immutable, vis.clone(), Some("input"));
|
||||
self.register_builtin_py_impl(
|
||||
"globals!",
|
||||
t_globals,
|
||||
Immutable,
|
||||
vis.clone(),
|
||||
Some("globals"),
|
||||
);
|
||||
self.register_builtin_py_impl("locals!", t_locals, Immutable, vis.clone(), Some("locals"));
|
||||
self.register_builtin_py_impl("next!", t_next, Immutable, vis.clone(), Some("next"));
|
||||
self.register_py_builtin("open!", t_open, Some("open"), 198);
|
||||
let name = if cfg!(feature = "py_compatible") {
|
||||
"if"
|
||||
} else {
|
||||
"if__"
|
||||
};
|
||||
self.register_builtin_py_impl("if!", t_if, Immutable, vis, Some(name));
|
||||
self.register_builtin_py_impl("if!", t_if, Immutable, vis.clone(), Some(name));
|
||||
let name = if cfg!(feature = "py_compatible") {
|
||||
"for"
|
||||
} else {
|
||||
"for__"
|
||||
};
|
||||
self.register_builtin_py_impl("for!", t_for, Immutable, vis, Some(name));
|
||||
self.register_builtin_py_impl("for!", t_for, Immutable, vis.clone(), Some(name));
|
||||
let name = if cfg!(feature = "py_compatible") {
|
||||
"while"
|
||||
} else {
|
||||
"while__"
|
||||
};
|
||||
self.register_builtin_py_impl("while!", t_while, Immutable, vis, Some(name));
|
||||
self.register_builtin_py_impl("while!", t_while, Immutable, vis.clone(), Some(name));
|
||||
let name = if cfg!(feature = "py_compatible") {
|
||||
"with"
|
||||
} else {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::vis::Visibility;
|
||||
|
||||
use crate::ty::constructors::*;
|
||||
use crate::ty::typaram::TyParam;
|
||||
use crate::ty::value::ValueObj;
|
||||
use crate::ty::Type;
|
||||
use crate::ty::{Type, Visibility};
|
||||
use ParamSpec as PS;
|
||||
use Type::*;
|
||||
|
||||
|
@ -14,7 +13,6 @@ use crate::context::{ConstTemplate, Context, DefaultInfo, ParamSpec};
|
|||
use crate::varinfo::Mutability;
|
||||
use DefaultInfo::*;
|
||||
use Mutability::*;
|
||||
use Visibility::*;
|
||||
|
||||
impl Context {
|
||||
/// see std/prelude.er
|
||||
|
@ -24,9 +22,9 @@ impl Context {
|
|||
// push_subtype_boundなどはユーザー定義APIの型境界決定のために使用する
|
||||
pub(super) fn init_builtin_traits(&mut self) {
|
||||
let vis = if cfg!(feature = "py_compatible") {
|
||||
Public
|
||||
Visibility::BUILTIN_PUBLIC
|
||||
} else {
|
||||
Private
|
||||
Visibility::BUILTIN_PRIVATE
|
||||
};
|
||||
let unpack = Self::builtin_mono_trait(UNPACK, 2);
|
||||
let inheritable_type = Self::builtin_mono_trait(INHERITABLE_TYPE, 2);
|
||||
|
@ -36,25 +34,35 @@ impl Context {
|
|||
let immut_t = proj(Slf.clone(), IMMUT_TYPE);
|
||||
let f_t = func(vec![kw(KW_OLD, immut_t.clone())], None, vec![], immut_t);
|
||||
let t = pr1_met(ref_mut(Slf, None), f_t, NoneType).quantify();
|
||||
mutable.register_builtin_erg_decl(PROC_UPDATE, t, Public);
|
||||
mutable.register_builtin_erg_decl(PROC_UPDATE, t, Visibility::BUILTIN_PUBLIC);
|
||||
// REVIEW: Immutatable?
|
||||
let mut immutizable = Self::builtin_mono_trait(IMMUTIZABLE, 2);
|
||||
immutizable.register_superclass(mono(MUTABLE), &mutable);
|
||||
immutizable.register_builtin_erg_decl(IMMUT_TYPE, Type, Public);
|
||||
immutizable.register_builtin_erg_decl(IMMUT_TYPE, Type, Visibility::BUILTIN_PUBLIC);
|
||||
// REVIEW: Mutatable?
|
||||
let mut mutizable = Self::builtin_mono_trait(MUTIZABLE, 2);
|
||||
mutizable.register_builtin_erg_decl(MUTABLE_MUT_TYPE, Type, Public);
|
||||
mutizable.register_builtin_erg_decl(MUTABLE_MUT_TYPE, Type, Visibility::BUILTIN_PUBLIC);
|
||||
let pathlike = Self::builtin_mono_trait(PATH_LIKE, 2);
|
||||
/* Readable */
|
||||
let mut readable = Self::builtin_mono_trait(MUTABLE_READABLE, 2);
|
||||
let Slf = mono_q(SELF, subtypeof(mono(MUTABLE_READABLE)));
|
||||
let t_read = pr_met(ref_mut(Slf, None), vec![], None, vec![kw(KW_N, Int)], Str).quantify();
|
||||
readable.register_builtin_py_decl(PROC_READ, t_read, Public, Some(FUNC_READ));
|
||||
readable.register_builtin_py_decl(
|
||||
PROC_READ,
|
||||
t_read,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNC_READ),
|
||||
);
|
||||
/* Writable */
|
||||
let mut writable = Self::builtin_mono_trait(MUTABLE_WRITABLE, 2);
|
||||
let Slf = mono_q(SELF, subtypeof(mono(MUTABLE_WRITABLE)));
|
||||
let t_write = pr1_kw_met(ref_mut(Slf, None), kw("s", Str), Nat).quantify();
|
||||
writable.register_builtin_py_decl(PROC_WRITE, t_write, Public, Some(FUNC_WRITE));
|
||||
writable.register_builtin_py_decl(
|
||||
PROC_WRITE,
|
||||
t_write,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNC_WRITE),
|
||||
);
|
||||
// TODO: Add required methods
|
||||
let mut filelike = Self::builtin_mono_trait(FILE_LIKE, 2);
|
||||
filelike.register_superclass(mono(READABLE), &readable);
|
||||
|
@ -65,7 +73,12 @@ impl Context {
|
|||
let mut show = Self::builtin_mono_trait(SHOW, 2);
|
||||
let Slf = mono_q(SELF, subtypeof(mono(SHOW)));
|
||||
let t_show = fn0_met(ref_(Slf), Str).quantify();
|
||||
show.register_builtin_py_decl(TO_STR, t_show, Public, Some(FUNDAMENTAL_STR));
|
||||
show.register_builtin_py_decl(
|
||||
TO_STR,
|
||||
t_show,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNDAMENTAL_STR),
|
||||
);
|
||||
/* In */
|
||||
let mut in_ = Self::builtin_poly_trait(IN, vec![PS::t_nd(TY_T)], 2);
|
||||
let params = vec![PS::t_nd(TY_T)];
|
||||
|
@ -75,7 +88,7 @@ impl Context {
|
|||
let I = mono_q(TY_I, subtypeof(poly(IN, vec![ty_tp(T.clone())])));
|
||||
in_.register_superclass(poly(INPUT, vec![ty_tp(T.clone())]), &input);
|
||||
let op_t = fn1_met(T.clone(), I, Bool).quantify();
|
||||
in_.register_builtin_erg_decl(OP_IN, op_t, Public);
|
||||
in_.register_builtin_erg_decl(OP_IN, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
/* Eq */
|
||||
// Erg does not have a trait equivalent to `PartialEq` in Rust
|
||||
// This means, Erg's `Float` cannot be compared with other `Float`
|
||||
|
@ -84,13 +97,13 @@ impl Context {
|
|||
let Slf = mono_q(SELF, subtypeof(mono(EQ)));
|
||||
// __eq__: |Self <: Eq| (self: Self, other: Self) -> Bool
|
||||
let op_t = fn1_met(Slf.clone(), Slf, Bool).quantify();
|
||||
eq.register_builtin_erg_decl(OP_EQ, op_t, Public);
|
||||
eq.register_builtin_erg_decl(OP_EQ, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
/* Ord */
|
||||
let mut ord = Self::builtin_mono_trait(ORD, 2);
|
||||
ord.register_superclass(mono(EQ), &eq);
|
||||
let Slf = mono_q(SELF, subtypeof(mono(ORD)));
|
||||
let op_t = fn1_met(Slf.clone(), Slf, or(mono(ORDERING), NoneType)).quantify();
|
||||
ord.register_builtin_erg_decl(OP_CMP, op_t, Public);
|
||||
ord.register_builtin_erg_decl(OP_CMP, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
// FIXME: poly trait
|
||||
/* Num */
|
||||
let num = Self::builtin_mono_trait(NUM, 2);
|
||||
|
@ -104,24 +117,29 @@ impl Context {
|
|||
seq.register_superclass(poly(OUTPUT, vec![ty_tp(T.clone())]), &output);
|
||||
let Slf = mono_q(SELF, subtypeof(poly(SEQ, vec![TyParam::erased(Type)])));
|
||||
let t = fn0_met(Slf.clone(), Nat).quantify();
|
||||
seq.register_builtin_erg_decl(FUNC_LEN, t, Public);
|
||||
seq.register_builtin_erg_decl(FUNC_LEN, t, Visibility::BUILTIN_PUBLIC);
|
||||
let t = fn1_met(Slf, Nat, T.clone()).quantify();
|
||||
// Seq.get: |Self <: Seq(T)| Self.(Nat) -> T
|
||||
seq.register_builtin_erg_decl(FUNC_GET, t, Public);
|
||||
seq.register_builtin_erg_decl(FUNC_GET, t, Visibility::BUILTIN_PUBLIC);
|
||||
/* Iterable */
|
||||
let mut iterable = Self::builtin_poly_trait(ITERABLE, vec![PS::t_nd(TY_T)], 2);
|
||||
iterable.register_superclass(poly(OUTPUT, vec![ty_tp(T.clone())]), &output);
|
||||
let Slf = mono_q(SELF, subtypeof(poly(ITERABLE, vec![ty_tp(T.clone())])));
|
||||
let t = fn0_met(Slf.clone(), proj(Slf, ITER)).quantify();
|
||||
iterable.register_builtin_py_decl(FUNC_ITER, t, Public, Some(FUNDAMENTAL_ITER));
|
||||
iterable.register_builtin_erg_decl(ITER, Type, Public);
|
||||
iterable.register_builtin_py_decl(
|
||||
FUNC_ITER,
|
||||
t,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNDAMENTAL_ITER),
|
||||
);
|
||||
iterable.register_builtin_erg_decl(ITER, Type, Visibility::BUILTIN_PUBLIC);
|
||||
let mut context_manager = Self::builtin_mono_trait(CONTEXT_MANAGER, 2);
|
||||
let Slf = mono_q(SELF, subtypeof(mono(CONTEXT_MANAGER)));
|
||||
let t = fn0_met(Slf.clone(), NoneType).quantify();
|
||||
context_manager.register_builtin_py_decl(
|
||||
FUNDAMENTAL_ENTER,
|
||||
t,
|
||||
Public,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNDAMENTAL_ENTER),
|
||||
);
|
||||
let t = fn_met(
|
||||
|
@ -139,7 +157,7 @@ impl Context {
|
|||
context_manager.register_builtin_py_decl(
|
||||
FUNDAMENTAL_EXIT,
|
||||
t,
|
||||
Public,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNDAMENTAL_EXIT),
|
||||
);
|
||||
let R = mono_q(TY_R, instanceof(Type));
|
||||
|
@ -152,111 +170,141 @@ impl Context {
|
|||
add.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
|
||||
let Slf = mono_q(SELF, subtypeof(poly(ADD, ty_params.clone())));
|
||||
let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify();
|
||||
add.register_builtin_erg_decl(OP_ADD, op_t, Public);
|
||||
add.register_builtin_erg_decl(OUTPUT, Type, Public);
|
||||
add.register_builtin_erg_decl(OP_ADD, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
add.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
|
||||
/* Sub */
|
||||
let mut sub = Self::builtin_poly_trait(SUB, params.clone(), 2);
|
||||
sub.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
|
||||
let Slf = mono_q(SELF, subtypeof(poly(SUB, ty_params.clone())));
|
||||
let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify();
|
||||
sub.register_builtin_erg_decl(OP_SUB, op_t, Public);
|
||||
sub.register_builtin_erg_decl(OUTPUT, Type, Public);
|
||||
sub.register_builtin_erg_decl(OP_SUB, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
sub.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
|
||||
/* Mul */
|
||||
let mut mul = Self::builtin_poly_trait(MUL, params.clone(), 2);
|
||||
mul.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
|
||||
let Slf = mono_q(SELF, subtypeof(poly(MUL, ty_params.clone())));
|
||||
let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify();
|
||||
mul.register_builtin_erg_decl(OP_MUL, op_t, Public);
|
||||
mul.register_builtin_erg_decl(OUTPUT, Type, Public);
|
||||
mul.register_builtin_erg_decl(OP_MUL, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
mul.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
|
||||
/* Div */
|
||||
let mut div = Self::builtin_poly_trait(DIV, params.clone(), 2);
|
||||
div.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
|
||||
let Slf = mono_q(SELF, subtypeof(poly(DIV, ty_params.clone())));
|
||||
let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify();
|
||||
div.register_builtin_erg_decl(OP_DIV, op_t, Public);
|
||||
div.register_builtin_erg_decl(OUTPUT, Type, Public);
|
||||
div.register_builtin_erg_decl(OP_DIV, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
div.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
|
||||
/* FloorDiv */
|
||||
let mut floor_div = Self::builtin_poly_trait(FLOOR_DIV, params, 2);
|
||||
floor_div.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output);
|
||||
let Slf = mono_q(SELF, subtypeof(poly(FLOOR_DIV, ty_params.clone())));
|
||||
let op_t = fn1_met(Slf.clone(), R, proj(Slf.clone(), OUTPUT)).quantify();
|
||||
floor_div.register_builtin_erg_decl(OP_FLOOR_DIV, op_t, Public);
|
||||
floor_div.register_builtin_erg_decl(OUTPUT, Type, Public);
|
||||
floor_div.register_builtin_erg_decl(OP_FLOOR_DIV, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
floor_div.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
|
||||
/* Pos */
|
||||
let mut pos = Self::builtin_mono_trait(POS, 2);
|
||||
let _Slf = mono_q(SELF, subtypeof(mono(POS)));
|
||||
let op_t = fn0_met(_Slf.clone(), proj(_Slf, OUTPUT)).quantify();
|
||||
pos.register_builtin_erg_decl(OP_POS, op_t, Public);
|
||||
pos.register_builtin_erg_decl(OUTPUT, Type, Public);
|
||||
pos.register_builtin_erg_decl(OP_POS, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
pos.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
|
||||
/* Neg */
|
||||
let mut neg = Self::builtin_mono_trait(NEG, 2);
|
||||
let _Slf = mono_q(SELF, subtypeof(mono(NEG)));
|
||||
let op_t = fn0_met(_Slf.clone(), proj(_Slf, OUTPUT)).quantify();
|
||||
neg.register_builtin_erg_decl(OP_NEG, op_t, Public);
|
||||
neg.register_builtin_erg_decl(OUTPUT, Type, Public);
|
||||
self.register_builtin_type(mono(UNPACK), unpack, vis, Const, None);
|
||||
neg.register_builtin_erg_decl(OP_NEG, op_t, Visibility::BUILTIN_PUBLIC);
|
||||
neg.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC);
|
||||
self.register_builtin_type(mono(UNPACK), unpack, vis.clone(), Const, None);
|
||||
self.register_builtin_type(
|
||||
mono(INHERITABLE_TYPE),
|
||||
inheritable_type,
|
||||
Private,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(mono(NAMED), named, vis, Const, None);
|
||||
self.register_builtin_type(mono(MUTABLE), mutable, vis, Const, None);
|
||||
self.register_builtin_type(mono(IMMUTIZABLE), immutizable, vis, Const, None);
|
||||
self.register_builtin_type(mono(MUTIZABLE), mutizable, vis, Const, None);
|
||||
self.register_builtin_type(mono(PATH_LIKE), pathlike, vis, Const, None);
|
||||
self.register_builtin_type(mono(NAMED), named, vis.clone(), Const, None);
|
||||
self.register_builtin_type(mono(MUTABLE), mutable, vis.clone(), Const, None);
|
||||
self.register_builtin_type(mono(IMMUTIZABLE), immutizable, vis.clone(), Const, None);
|
||||
self.register_builtin_type(mono(MUTIZABLE), mutizable, vis.clone(), Const, None);
|
||||
self.register_builtin_type(mono(PATH_LIKE), pathlike, vis.clone(), Const, None);
|
||||
self.register_builtin_type(
|
||||
mono(MUTABLE_READABLE),
|
||||
readable,
|
||||
Private,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Const,
|
||||
Some(READABLE),
|
||||
);
|
||||
self.register_builtin_type(
|
||||
mono(MUTABLE_WRITABLE),
|
||||
writable,
|
||||
Private,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Const,
|
||||
Some(WRITABLE),
|
||||
);
|
||||
self.register_builtin_type(mono(FILE_LIKE), filelike, vis, Const, None);
|
||||
self.register_builtin_type(mono(MUTABLE_FILE_LIKE), filelike_mut, vis, Const, None);
|
||||
self.register_builtin_type(mono(SHOW), show, vis, Const, None);
|
||||
self.register_builtin_type(mono(FILE_LIKE), filelike, vis.clone(), Const, None);
|
||||
self.register_builtin_type(
|
||||
mono(MUTABLE_FILE_LIKE),
|
||||
filelike_mut,
|
||||
vis.clone(),
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(mono(SHOW), show, vis.clone(), Const, None);
|
||||
self.register_builtin_type(
|
||||
poly(INPUT, vec![ty_tp(T.clone())]),
|
||||
input,
|
||||
Private,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(
|
||||
poly(OUTPUT, vec![ty_tp(T.clone())]),
|
||||
output,
|
||||
Private,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(
|
||||
poly(IN, vec![ty_tp(T.clone())]),
|
||||
in_,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(mono(EQ), eq, vis.clone(), Const, None);
|
||||
self.register_builtin_type(mono(ORD), ord, vis.clone(), Const, None);
|
||||
self.register_builtin_type(mono(NUM), num, vis.clone(), Const, None);
|
||||
self.register_builtin_type(
|
||||
poly(SEQ, vec![ty_tp(T.clone())]),
|
||||
seq,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(poly(IN, vec![ty_tp(T.clone())]), in_, Private, Const, None);
|
||||
self.register_builtin_type(mono(EQ), eq, vis, Const, None);
|
||||
self.register_builtin_type(mono(ORD), ord, vis, Const, None);
|
||||
self.register_builtin_type(mono(NUM), num, vis, Const, None);
|
||||
self.register_builtin_type(poly(SEQ, vec![ty_tp(T.clone())]), seq, Private, Const, None);
|
||||
self.register_builtin_type(
|
||||
poly(ITERABLE, vec![ty_tp(T)]),
|
||||
iterable,
|
||||
Private,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(mono(CONTEXT_MANAGER), context_manager, Private, Const, None);
|
||||
self.register_builtin_type(poly(ADD, ty_params.clone()), add, vis, Const, None);
|
||||
self.register_builtin_type(poly(SUB, ty_params.clone()), sub, vis, Const, None);
|
||||
self.register_builtin_type(poly(MUL, ty_params.clone()), mul, vis, Const, None);
|
||||
self.register_builtin_type(poly(DIV, ty_params.clone()), div, vis, Const, None);
|
||||
self.register_builtin_type(poly(FLOOR_DIV, ty_params), floor_div, vis, Const, None);
|
||||
self.register_builtin_type(mono(POS), pos, vis, Const, None);
|
||||
self.register_builtin_type(
|
||||
mono(CONTEXT_MANAGER),
|
||||
context_manager,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(poly(ADD, ty_params.clone()), add, vis.clone(), Const, None);
|
||||
self.register_builtin_type(poly(SUB, ty_params.clone()), sub, vis.clone(), Const, None);
|
||||
self.register_builtin_type(poly(MUL, ty_params.clone()), mul, vis.clone(), Const, None);
|
||||
self.register_builtin_type(poly(DIV, ty_params.clone()), div, vis.clone(), Const, None);
|
||||
self.register_builtin_type(
|
||||
poly(FLOOR_DIV, ty_params),
|
||||
floor_div,
|
||||
vis.clone(),
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(mono(POS), pos, vis.clone(), Const, None);
|
||||
self.register_builtin_type(mono(NEG), neg, vis, Const, None);
|
||||
self.register_const_param_defaults(
|
||||
ADD,
|
||||
|
|
|
@ -5,28 +5,27 @@ use std::path::{Path, PathBuf};
|
|||
use erg_common::config::{ErgConfig, Input};
|
||||
use erg_common::env::{erg_py_external_lib_path, erg_pystd_path, erg_std_path};
|
||||
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
|
||||
use erg_common::levenshtein::get_similar_name;
|
||||
use erg_common::levenshtein;
|
||||
use erg_common::pathutil::add_postfix_foreach;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{Locational, NoTypeDisplay, Stream};
|
||||
use erg_common::vis::Visibility;
|
||||
use erg_common::triple::Triple;
|
||||
use erg_common::Str;
|
||||
use erg_common::{
|
||||
fmt_option, fmt_slice, log, normalize_path, option_enum_unwrap, set, switch_lang,
|
||||
};
|
||||
use Type::*;
|
||||
|
||||
use ast::VarName;
|
||||
use erg_parser::ast::{self, Identifier};
|
||||
use erg_parser::ast::{self, Identifier, VarName};
|
||||
use erg_parser::token::Token;
|
||||
|
||||
use crate::ty::constructors::{anon, free_var, func, mono, poly, proc, proj, ref_, subr_t};
|
||||
use crate::ty::free::Constraint;
|
||||
use crate::ty::typaram::TyParam;
|
||||
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||
use crate::ty::{HasType, ParamTy, SubrKind, SubrType, Type};
|
||||
use crate::ty::{HasType, ParamTy, SubrKind, SubrType, Type, Visibility};
|
||||
use Type::*;
|
||||
|
||||
use crate::context::instantiate::ConstTemplate;
|
||||
use crate::context::instantiate_spec::ConstTemplate;
|
||||
use crate::context::{Context, RegistrationMode, TraitImpl, TyVarCache, Variance};
|
||||
use crate::error::{
|
||||
binop_to_dname, readable_name, unaryop_to_dname, SingleTyCheckResult, TyCheckError,
|
||||
|
@ -36,9 +35,8 @@ use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind};
|
|||
use crate::{feature_error, hir};
|
||||
use crate::{unreachable_error, AccessKind};
|
||||
use RegistrationMode::*;
|
||||
use Visibility::*;
|
||||
|
||||
use super::instantiate::ParamKind;
|
||||
use super::instantiate_spec::ParamKind;
|
||||
use super::{ContextKind, MethodInfo};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -105,7 +103,7 @@ impl Context {
|
|||
pub fn get_singular_ctx_by_hir_expr(
|
||||
&self,
|
||||
obj: &hir::Expr,
|
||||
namespace: &Str,
|
||||
namespace: &Context,
|
||||
) -> SingleTyCheckResult<&Context> {
|
||||
match obj {
|
||||
hir::Expr::Accessor(hir::Accessor::Ident(ident)) => {
|
||||
|
@ -132,19 +130,22 @@ impl Context {
|
|||
pub(crate) fn get_singular_ctx_by_ident(
|
||||
&self,
|
||||
ident: &ast::Identifier,
|
||||
namespace: &Str,
|
||||
namespace: &Context,
|
||||
) -> SingleTyCheckResult<&Context> {
|
||||
self.get_mod(ident.inspect())
|
||||
.or_else(|| self.rec_local_get_type(ident.inspect()).map(|(_, ctx)| ctx))
|
||||
.or_else(|| self.rec_get_patch(ident.inspect()))
|
||||
.ok_or_else(|| {
|
||||
TyCheckError::no_var_error(
|
||||
let (similar_info, similar_name) =
|
||||
self.get_similar_name_and_info(ident.inspect()).unzip();
|
||||
TyCheckError::detailed_no_var_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
namespace.name.to_string(),
|
||||
ident.inspect(),
|
||||
self.get_similar_name(ident.inspect()),
|
||||
similar_name,
|
||||
similar_info,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -170,7 +171,7 @@ impl Context {
|
|||
pub(crate) fn get_singular_ctx(
|
||||
&self,
|
||||
obj: &ast::Expr,
|
||||
namespace: &Str,
|
||||
namespace: &Context,
|
||||
) -> SingleTyCheckResult<&Context> {
|
||||
match obj {
|
||||
ast::Expr::Accessor(ast::Accessor::Ident(ident)) => {
|
||||
|
@ -342,16 +343,16 @@ impl Context {
|
|||
ident: &Identifier,
|
||||
acc_kind: AccessKind,
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> SingleTyCheckResult<VarInfo> {
|
||||
namespace: &Context,
|
||||
) -> Triple<VarInfo, TyCheckError> {
|
||||
if let Some(vi) = self.get_current_scope_var(&ident.name) {
|
||||
match self.validate_visibility(ident, vi, input, namespace) {
|
||||
Ok(()) => {
|
||||
return Ok(vi.clone());
|
||||
return Triple::Ok(vi.clone());
|
||||
}
|
||||
Err(err) => {
|
||||
if !acc_kind.is_local() {
|
||||
return Err(err);
|
||||
return Triple::Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -359,21 +360,21 @@ impl Context {
|
|||
.future_defined_locals
|
||||
.get_key_value(&ident.inspect()[..])
|
||||
{
|
||||
return Err(TyCheckError::access_before_def_error(
|
||||
return Triple::Err(TyCheckError::access_before_def_error(
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
namespace.name.to_string(),
|
||||
ident.inspect(),
|
||||
name.ln_begin().unwrap_or(0),
|
||||
self.get_similar_name(ident.inspect()),
|
||||
));
|
||||
} else if let Some((name, _vi)) = self.deleted_locals.get_key_value(&ident.inspect()[..]) {
|
||||
return Err(TyCheckError::access_deleted_var_error(
|
||||
return Triple::Err(TyCheckError::access_deleted_var_error(
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
namespace.name.to_string(),
|
||||
ident.inspect(),
|
||||
name.ln_begin().unwrap_or(0),
|
||||
self.get_similar_name(ident.inspect()),
|
||||
|
@ -381,20 +382,22 @@ impl Context {
|
|||
}
|
||||
if acc_kind.is_local() {
|
||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
return match parent.rec_get_var_info(ident, acc_kind, input, namespace) {
|
||||
Ok(vi) => Ok(vi),
|
||||
Err(err) => Err(err),
|
||||
};
|
||||
return parent.rec_get_var_info(ident, acc_kind, input, namespace);
|
||||
}
|
||||
}
|
||||
Err(TyCheckError::no_var_error(
|
||||
/*
|
||||
let (similar_info, similar_name) = self.get_similar_name_and_info(ident.inspect()).unzip();
|
||||
Err(TyCheckError::detailed_no_var_error(
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
ident.inspect(),
|
||||
self.get_similar_name(ident.inspect()),
|
||||
similar_name,
|
||||
similar_info,
|
||||
))
|
||||
*/
|
||||
Triple::None
|
||||
}
|
||||
|
||||
pub(crate) fn rec_get_decl_info(
|
||||
|
@ -402,8 +405,8 @@ impl Context {
|
|||
ident: &Identifier,
|
||||
acc_kind: AccessKind,
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> SingleTyCheckResult<VarInfo> {
|
||||
namespace: &Context,
|
||||
) -> Triple<VarInfo, TyCheckError> {
|
||||
if let Some(vi) = self
|
||||
.decls
|
||||
.get(&ident.inspect()[..])
|
||||
|
@ -411,11 +414,11 @@ impl Context {
|
|||
{
|
||||
match self.validate_visibility(ident, vi, input, namespace) {
|
||||
Ok(()) => {
|
||||
return Ok(vi.clone());
|
||||
return Triple::Ok(vi.clone());
|
||||
}
|
||||
Err(err) => {
|
||||
if !acc_kind.is_local() {
|
||||
return Err(err);
|
||||
return Triple::Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -425,14 +428,15 @@ impl Context {
|
|||
return parent.rec_get_decl_info(ident, acc_kind, input, namespace);
|
||||
}
|
||||
}
|
||||
Err(TyCheckError::no_var_error(
|
||||
/*Err(TyCheckError::no_var_error(
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
ident.inspect(),
|
||||
self.get_similar_name(ident.inspect()),
|
||||
))
|
||||
))*/
|
||||
Triple::None
|
||||
}
|
||||
|
||||
pub(crate) fn get_attr_info(
|
||||
|
@ -440,51 +444,59 @@ impl Context {
|
|||
obj: &hir::Expr,
|
||||
ident: &Identifier,
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> SingleTyCheckResult<VarInfo> {
|
||||
namespace: &Context,
|
||||
) -> Triple<VarInfo, TyCheckError> {
|
||||
let self_t = obj.t();
|
||||
let name = ident.name.token();
|
||||
match self.get_attr_info_from_attributive(&self_t, ident, namespace) {
|
||||
Ok(vi) => {
|
||||
return Ok(vi);
|
||||
match self.get_attr_info_from_attributive(&self_t, ident) {
|
||||
Triple::Ok(vi) => {
|
||||
return Triple::Ok(vi);
|
||||
}
|
||||
Err(e) if e.core.kind == ErrorKind::AttributeError => {}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
Triple::Err(e) => {
|
||||
return Triple::Err(e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Ok(singular_ctx) = self.get_singular_ctx_by_hir_expr(obj, namespace) {
|
||||
match singular_ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) {
|
||||
Ok(vi) => {
|
||||
return Ok(vi);
|
||||
Triple::Ok(vi) => {
|
||||
return Triple::Ok(vi);
|
||||
}
|
||||
Err(e) if e.core.kind == ErrorKind::NameError => {}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
Triple::Err(e) => {
|
||||
return Triple::Err(e);
|
||||
}
|
||||
Triple::None => {}
|
||||
}
|
||||
}
|
||||
match self.get_attr_from_nominal_t(obj, ident, input, namespace) {
|
||||
Ok(vi) => {
|
||||
Triple::Ok(vi) => {
|
||||
if let Some(self_t) = vi.t.self_t() {
|
||||
self.sub_unify(obj.ref_t(), self_t, obj, Some(&"self".into()))
|
||||
.map_err(|mut e| e.remove(0))?;
|
||||
}
|
||||
return Ok(vi);
|
||||
}
|
||||
Err(e) if e.core.kind == ErrorKind::AttributeError => {}
|
||||
match self
|
||||
.sub_unify(obj.ref_t(), self_t, obj, Some(&"self".into()))
|
||||
.map_err(|mut e| e.remove(0))
|
||||
{
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
return Triple::Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Triple::Ok(vi);
|
||||
}
|
||||
Triple::Err(e) => {
|
||||
return Triple::Err(e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
for patch in self.find_patches_of(obj.ref_t()) {
|
||||
if let Some(vi) = patch
|
||||
.locals
|
||||
.get(ident.inspect())
|
||||
.or_else(|| patch.decls.get(ident.inspect()))
|
||||
{
|
||||
self.validate_visibility(ident, vi, input, namespace)?;
|
||||
return Ok(vi.clone());
|
||||
return match self.validate_visibility(ident, vi, input, namespace) {
|
||||
Ok(_) => Triple::Ok(vi.clone()),
|
||||
Err(e) => Triple::Err(e),
|
||||
};
|
||||
}
|
||||
for (_, methods_ctx) in patch.methods_list.iter() {
|
||||
if let Some(vi) = methods_ctx
|
||||
|
@ -492,12 +504,15 @@ impl Context {
|
|||
.get(ident.inspect())
|
||||
.or_else(|| methods_ctx.decls.get(ident.inspect()))
|
||||
{
|
||||
self.validate_visibility(ident, vi, input, namespace)?;
|
||||
return Ok(vi.clone());
|
||||
return match self.validate_visibility(ident, vi, input, namespace) {
|
||||
Ok(_) => Triple::Ok(vi.clone()),
|
||||
Err(e) => Triple::Err(e),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(TyCheckError::no_attr_error(
|
||||
Triple::None
|
||||
/*Err(TyCheckError::no_attr_error(
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
name.loc(),
|
||||
|
@ -505,7 +520,7 @@ impl Context {
|
|||
&self_t,
|
||||
name.inspect(),
|
||||
self.get_similar_attr(&self_t, name.inspect()),
|
||||
))
|
||||
))*/
|
||||
}
|
||||
|
||||
fn get_attr_from_nominal_t(
|
||||
|
@ -513,39 +528,45 @@ impl Context {
|
|||
obj: &hir::Expr,
|
||||
ident: &Identifier,
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
) -> SingleTyCheckResult<VarInfo> {
|
||||
namespace: &Context,
|
||||
) -> Triple<VarInfo, TyCheckError> {
|
||||
let self_t = obj.t();
|
||||
if let Some(sups) = self.get_nominal_super_type_ctxs(&self_t) {
|
||||
for ctx in sups {
|
||||
match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) {
|
||||
Ok(vi) => {
|
||||
return Ok(vi);
|
||||
Triple::Ok(vi) => {
|
||||
return Triple::Ok(vi);
|
||||
}
|
||||
Err(e) if e.core.kind == ErrorKind::NameError => {}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
Triple::Err(e) => {
|
||||
return Triple::Err(e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
// if self is a methods context
|
||||
if let Some(ctx) = self.get_same_name_context(&ctx.name) {
|
||||
match ctx.rec_get_var_info(ident, AccessKind::Method, input, namespace) {
|
||||
Ok(vi) => {
|
||||
return Ok(vi);
|
||||
Triple::Ok(vi) => {
|
||||
return Triple::Ok(vi);
|
||||
}
|
||||
Err(e) if e.core.kind == ErrorKind::NameError => {}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
Triple::Err(e) => {
|
||||
return Triple::Err(e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let coerced = self
|
||||
let coerced = match self
|
||||
.deref_tyvar(obj.t(), Variance::Covariant, &set! {}, &())
|
||||
.map_err(|mut es| es.remove(0))?;
|
||||
.map_err(|mut es| es.remove(0))
|
||||
{
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
return Triple::Err(e);
|
||||
}
|
||||
};
|
||||
if obj.ref_t() != &coerced {
|
||||
for ctx in self.get_nominal_super_type_ctxs(&coerced).ok_or_else(|| {
|
||||
let ctxs = match self.get_nominal_super_type_ctxs(&coerced).ok_or_else(|| {
|
||||
TyCheckError::type_not_found(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -553,31 +574,37 @@ impl Context {
|
|||
self.caused_by(),
|
||||
&coerced,
|
||||
)
|
||||
})? {
|
||||
match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) {
|
||||
Ok(vi) => {
|
||||
obj.ref_t().coerce();
|
||||
return Ok(vi);
|
||||
}
|
||||
Err(e) if e.core.kind == ErrorKind::NameError => {}
|
||||
}) {
|
||||
Ok(ctxs) => ctxs,
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
return Triple::Err(e);
|
||||
}
|
||||
};
|
||||
for ctx in ctxs {
|
||||
match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) {
|
||||
Triple::Ok(vi) => {
|
||||
obj.ref_t().coerce();
|
||||
return Triple::Ok(vi);
|
||||
}
|
||||
Triple::Err(e) => {
|
||||
return Triple::Err(e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Some(ctx) = self.get_same_name_context(&ctx.name) {
|
||||
match ctx.rec_get_var_info(ident, AccessKind::Method, input, namespace) {
|
||||
Ok(vi) => {
|
||||
return Ok(vi);
|
||||
Triple::Ok(vi) => {
|
||||
return Triple::Ok(vi);
|
||||
}
|
||||
Err(e) if e.core.kind == ErrorKind::NameError => {}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
Triple::Err(e) => {
|
||||
return Triple::Err(e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(TyCheckError::no_attr_error(
|
||||
/*Err(TyCheckError::no_attr_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
|
@ -585,7 +612,8 @@ impl Context {
|
|||
&self_t,
|
||||
ident.inspect(),
|
||||
self.get_similar_attr(&self_t, ident.inspect()),
|
||||
))
|
||||
))*/
|
||||
Triple::None
|
||||
}
|
||||
|
||||
/// get type from given attributive type (Record).
|
||||
|
@ -594,41 +622,43 @@ impl Context {
|
|||
&self,
|
||||
t: &Type,
|
||||
ident: &Identifier,
|
||||
namespace: &Str,
|
||||
) -> SingleTyCheckResult<VarInfo> {
|
||||
) -> Triple<VarInfo, TyCheckError> {
|
||||
match t {
|
||||
// (obj: Never).foo: Never
|
||||
Type::Never => Ok(VarInfo::ILLEGAL.clone()),
|
||||
Type::Never => Triple::Ok(VarInfo::ILLEGAL.clone()),
|
||||
Type::FreeVar(fv) if fv.is_linked() => {
|
||||
self.get_attr_info_from_attributive(&fv.crack(), ident, namespace)
|
||||
self.get_attr_info_from_attributive(&fv.crack(), ident)
|
||||
}
|
||||
Type::FreeVar(fv) /* if fv.is_unbound() */ => {
|
||||
let sup = fv.get_super().unwrap();
|
||||
self.get_attr_info_from_attributive(&sup, ident, namespace)
|
||||
self.get_attr_info_from_attributive(&sup, ident)
|
||||
}
|
||||
Type::Ref(t) => self.get_attr_info_from_attributive(t, ident, namespace),
|
||||
Type::Ref(t) => self.get_attr_info_from_attributive(t, ident),
|
||||
Type::RefMut { before, .. } => {
|
||||
self.get_attr_info_from_attributive(before, ident, namespace)
|
||||
self.get_attr_info_from_attributive(before, ident)
|
||||
}
|
||||
Type::Refinement(refine) => {
|
||||
self.get_attr_info_from_attributive(&refine.t, ident, namespace)
|
||||
self.get_attr_info_from_attributive(&refine.t, ident)
|
||||
}
|
||||
Type::Record(record) => {
|
||||
if let Some(attr_t) = record.get(ident.inspect()) {
|
||||
if let Some((field, attr_t)) = record.get_key_value(ident.inspect()) {
|
||||
let muty = Mutability::from(&ident.inspect()[..]);
|
||||
let vi = VarInfo::new(
|
||||
attr_t.clone(),
|
||||
muty,
|
||||
Public,
|
||||
Visibility::new(field.vis.clone(), Str::ever("<dummy>")),
|
||||
VarKind::Builtin,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
AbsLocation::unknown(),
|
||||
);
|
||||
Ok(vi)
|
||||
if let Err(err) = self.validate_visibility(ident, &vi, &self.cfg.input, self) {
|
||||
return Triple::Err(err);
|
||||
}
|
||||
Triple::Ok(vi)
|
||||
} else {
|
||||
Err(TyCheckError::no_attr_error(
|
||||
/*Err(TyCheckError::no_attr_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
|
@ -636,73 +666,12 @@ impl Context {
|
|||
t,
|
||||
ident.inspect(),
|
||||
self.get_similar_attr(t, ident.inspect()),
|
||||
))
|
||||
}
|
||||
}
|
||||
Type::Structural(t) => self.get_attr_info_from_attributive(t, ident, namespace),
|
||||
other => {
|
||||
if let Some(v) = self.rec_get_const_obj(&other.local_name()) {
|
||||
match v {
|
||||
ValueObj::Type(TypeObj::Generated(gen)) => self
|
||||
.get_gen_t_require_attr_t(gen, &ident.inspect()[..])
|
||||
.map(|attr_t| {
|
||||
let muty = Mutability::from(&ident.inspect()[..]);
|
||||
VarInfo::new(
|
||||
attr_t.clone(),
|
||||
muty,
|
||||
Public,
|
||||
VarKind::Builtin,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
AbsLocation::unknown(),
|
||||
)
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
TyCheckError::no_attr_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
t,
|
||||
ident.inspect(),
|
||||
self.get_similar_attr(t, ident.inspect()),
|
||||
)
|
||||
}),
|
||||
ValueObj::Type(TypeObj::Builtin(_t)) => {
|
||||
// FIXME:
|
||||
Err(TyCheckError::no_attr_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
_t,
|
||||
ident.inspect(),
|
||||
self.get_similar_attr(_t, ident.inspect()),
|
||||
))
|
||||
}
|
||||
_other => Err(TyCheckError::no_attr_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
t,
|
||||
ident.inspect(),
|
||||
self.get_similar_attr(t, ident.inspect()),
|
||||
)),
|
||||
}
|
||||
} else {
|
||||
Err(TyCheckError::no_attr_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
namespace.into(),
|
||||
t,
|
||||
ident.inspect(),
|
||||
self.get_similar_attr(t, ident.inspect()),
|
||||
))
|
||||
))*/
|
||||
Triple::None
|
||||
}
|
||||
}
|
||||
Type::Structural(t) => self.get_attr_info_from_attributive(t, ident),
|
||||
_other => Triple::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,7 +681,7 @@ impl Context {
|
|||
obj: &hir::Expr,
|
||||
attr_name: &Option<Identifier>,
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
namespace: &Context,
|
||||
) -> SingleTyCheckResult<VarInfo> {
|
||||
if obj.ref_t() == Type::FAILURE {
|
||||
// (...Obj) -> Failure
|
||||
|
@ -750,11 +719,17 @@ impl Context {
|
|||
obj: &hir::Expr,
|
||||
attr_name: &Identifier,
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
namespace: &Context,
|
||||
) -> SingleTyCheckResult<VarInfo> {
|
||||
if let Ok(vi) = self.get_attr_info_from_attributive(obj.ref_t(), attr_name, namespace) {
|
||||
match self.get_attr_info_from_attributive(obj.ref_t(), attr_name) {
|
||||
Triple::Ok(vi) => {
|
||||
return Ok(vi);
|
||||
}
|
||||
Triple::Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
for ctx in self
|
||||
.get_nominal_super_type_ctxs(obj.ref_t())
|
||||
.ok_or_else(|| {
|
||||
|
@ -787,13 +762,13 @@ impl Context {
|
|||
}
|
||||
if let Some(ctx) = self.get_same_name_context(&ctx.name) {
|
||||
match ctx.rec_get_var_info(attr_name, AccessKind::Method, input, namespace) {
|
||||
Ok(t) => {
|
||||
Triple::Ok(t) => {
|
||||
return Ok(t);
|
||||
}
|
||||
Err(e) if e.core.kind == ErrorKind::NameError => {}
|
||||
Err(e) => {
|
||||
Triple::Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
Triple::None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -820,7 +795,7 @@ impl Context {
|
|||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
attr_name.loc(),
|
||||
namespace.into(),
|
||||
namespace.name.to_string(),
|
||||
obj.qual_name().unwrap_or("?"),
|
||||
obj.ref_t(),
|
||||
attr_name.inspect(),
|
||||
|
@ -863,7 +838,7 @@ impl Context {
|
|||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
attr_name.loc(),
|
||||
namespace.into(),
|
||||
namespace.name.to_string(),
|
||||
obj.ref_t(),
|
||||
attr_name.inspect(),
|
||||
self.get_similar_attr(obj.ref_t(), attr_name.inspect()),
|
||||
|
@ -875,34 +850,19 @@ impl Context {
|
|||
ident: &Identifier,
|
||||
vi: &VarInfo,
|
||||
input: &Input,
|
||||
namespace: &str,
|
||||
namespace: &Context,
|
||||
) -> SingleTyCheckResult<()> {
|
||||
if ident.vis() != vi.vis {
|
||||
Err(TyCheckError::visibility_error(
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
self.caused_by(),
|
||||
ident.inspect(),
|
||||
vi.vis,
|
||||
))
|
||||
// check if the private variable is loaded from the other scope
|
||||
} else if vi.vis.is_private()
|
||||
&& &self.name[..] != "<builtins>"
|
||||
&& &self.name[..] != namespace
|
||||
&& !namespace.contains(&self.name[..])
|
||||
{
|
||||
log!(err "{namespace}/{}", self.name);
|
||||
Err(TyCheckError::visibility_error(
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
self.caused_by(),
|
||||
ident.inspect(),
|
||||
Private,
|
||||
))
|
||||
} else {
|
||||
if vi.vis.compatible(&ident.acc_kind(), namespace) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(TyCheckError::visibility_error(
|
||||
input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
self.caused_by(),
|
||||
ident.inspect(),
|
||||
vi.vis.clone(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -931,18 +891,20 @@ impl Context {
|
|||
op: &Token,
|
||||
args: &[hir::PosArg],
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
namespace: &Context,
|
||||
) -> TyCheckResult<VarInfo> {
|
||||
erg_common::debug_power_assert!(args.len() == 2);
|
||||
let cont = binop_to_dname(op.inspect());
|
||||
// not a `Token::from_str(op.kind, cont)` because ops are defined as symbols
|
||||
let symbol = Token::symbol(cont);
|
||||
let t = self.rec_get_var_info(
|
||||
&Identifier::new(None, VarName::new(symbol.clone())),
|
||||
let t = self
|
||||
.rec_get_var_info(
|
||||
&Identifier::private_from_token(symbol.clone()),
|
||||
AccessKind::Name,
|
||||
input,
|
||||
namespace,
|
||||
)?;
|
||||
)
|
||||
.unwrap_to_result()?;
|
||||
let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t));
|
||||
self.get_call_t(&op, &None, args, &[], input, namespace)
|
||||
.map_err(|(_, errs)| {
|
||||
|
@ -952,7 +914,7 @@ impl Context {
|
|||
let vi = op_ident.vi.clone();
|
||||
let lhs = args[0].expr.clone();
|
||||
let rhs = args[1].expr.clone();
|
||||
let bin = hir::BinOp::new(op_ident.name.into_token(), lhs, rhs, vi);
|
||||
let bin = hir::BinOp::new(op_ident.raw.name.into_token(), lhs, rhs, vi);
|
||||
let errs = errs
|
||||
.into_iter()
|
||||
.map(|e| self.append_loc_info(e, bin.loc()))
|
||||
|
@ -966,17 +928,19 @@ impl Context {
|
|||
op: &Token,
|
||||
args: &[hir::PosArg],
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
namespace: &Context,
|
||||
) -> TyCheckResult<VarInfo> {
|
||||
erg_common::debug_power_assert!(args.len() == 1);
|
||||
let cont = unaryop_to_dname(op.inspect());
|
||||
let symbol = Token::symbol(cont);
|
||||
let vi = self.rec_get_var_info(
|
||||
&Identifier::new(None, VarName::new(symbol.clone())),
|
||||
let vi = self
|
||||
.rec_get_var_info(
|
||||
&Identifier::private_from_token(symbol.clone()),
|
||||
AccessKind::Name,
|
||||
input,
|
||||
namespace,
|
||||
)?;
|
||||
)
|
||||
.unwrap_to_result()?;
|
||||
let op = hir::Expr::Accessor(hir::Accessor::private(symbol, vi));
|
||||
self.get_call_t(&op, &None, args, &[], input, namespace)
|
||||
.map_err(|(_, errs)| {
|
||||
|
@ -985,7 +949,7 @@ impl Context {
|
|||
};
|
||||
let vi = op_ident.vi.clone();
|
||||
let expr = args[0].expr.clone();
|
||||
let unary = hir::UnaryOp::new(op_ident.name.into_token(), expr, vi);
|
||||
let unary = hir::UnaryOp::new(op_ident.raw.name.into_token(), expr, vi);
|
||||
let errs = errs
|
||||
.into_iter()
|
||||
.map(|e| self.append_loc_info(e, unary.loc()))
|
||||
|
@ -1118,10 +1082,8 @@ impl Context {
|
|||
if is_method {
|
||||
obj.clone()
|
||||
} else {
|
||||
let attr = hir::Attribute::new(
|
||||
obj.clone(),
|
||||
hir::Identifier::bare(ident.dot.clone(), ident.name.clone()),
|
||||
);
|
||||
let attr =
|
||||
hir::Attribute::new(obj.clone(), hir::Identifier::bare(ident.clone()));
|
||||
hir::Expr::Accessor(hir::Accessor::Attr(attr))
|
||||
}
|
||||
} else {
|
||||
|
@ -1272,10 +1234,10 @@ impl Context {
|
|||
}
|
||||
}
|
||||
other => {
|
||||
let one = self.get_singular_ctx_by_hir_expr(obj, &self.name).ok();
|
||||
let one = self.get_singular_ctx_by_hir_expr(obj, self).ok();
|
||||
let one = one
|
||||
.zip(attr_name.as_ref())
|
||||
.and_then(|(ctx, attr)| ctx.get_singular_ctx_by_ident(attr, &self.name).ok())
|
||||
.and_then(|(ctx, attr)| ctx.get_singular_ctx_by_ident(attr, self).ok())
|
||||
.or(one);
|
||||
let two = obj
|
||||
.qual_name()
|
||||
|
@ -1354,7 +1316,8 @@ impl Context {
|
|||
))
|
||||
} else {
|
||||
let unknown_arg_errors = unknown_args.into_iter().map(|arg| {
|
||||
let similar = get_similar_name(subr_ty.param_names(), arg.keyword.inspect());
|
||||
let similar =
|
||||
levenshtein::get_similar_name(subr_ty.param_names(), arg.keyword.inspect());
|
||||
TyCheckError::unexpected_kw_arg_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1550,7 +1513,8 @@ impl Context {
|
|||
)
|
||||
})?;
|
||||
} else {
|
||||
let similar = get_similar_name(subr_ty.param_names(), arg.keyword.inspect());
|
||||
let similar =
|
||||
levenshtein::get_similar_name(subr_ty.param_names(), arg.keyword.inspect());
|
||||
return Err(TyCheckErrors::from(TyCheckError::unexpected_kw_arg_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1571,7 +1535,7 @@ impl Context {
|
|||
pos_args: &[hir::PosArg],
|
||||
kw_args: &[hir::KwArg],
|
||||
input: &Input,
|
||||
namespace: &Str,
|
||||
namespace: &Context,
|
||||
) -> Result<VarInfo, (Option<VarInfo>, TyCheckErrors)> {
|
||||
if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj {
|
||||
if local.vis().is_private() {
|
||||
|
@ -1692,18 +1656,27 @@ impl Context {
|
|||
}
|
||||
|
||||
pub(crate) fn get_similar_name(&self, name: &str) -> Option<&str> {
|
||||
get_similar_name(
|
||||
levenshtein::get_similar_name(
|
||||
self.dir().into_iter().map(|(vn, _)| &vn.inspect()[..]),
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn get_similar_name_and_info(&self, name: &str) -> Option<(&VarInfo, &str)> {
|
||||
levenshtein::get_similar_name_and_some(
|
||||
self.dir()
|
||||
.into_iter()
|
||||
.map(|(vn, vi)| (vi, &vn.inspect()[..])),
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn get_similar_attr_from_singular<'a>(
|
||||
&'a self,
|
||||
obj: &hir::Expr,
|
||||
name: &str,
|
||||
) -> Option<&'a str> {
|
||||
if let Ok(ctx) = self.get_singular_ctx_by_hir_expr(obj, &self.name) {
|
||||
if let Ok(ctx) = self.get_singular_ctx_by_hir_expr(obj, self) {
|
||||
if let Some(name) = ctx.get_similar_name(name) {
|
||||
return Some(name);
|
||||
}
|
||||
|
@ -1720,6 +1693,19 @@ impl Context {
|
|||
None
|
||||
}
|
||||
|
||||
pub(crate) fn get_similar_attr_and_info<'a>(
|
||||
&'a self,
|
||||
self_t: &'a Type,
|
||||
name: &str,
|
||||
) -> Option<(&'a VarInfo, &'a str)> {
|
||||
for ctx in self.get_nominal_super_type_ctxs(self_t)? {
|
||||
if let Some((vi, name)) = ctx.get_similar_name_and_info(name) {
|
||||
return Some((vi, name));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
// Returns what kind of variance the type has for each parameter Type.
|
||||
// Invariant for types not specified
|
||||
// selfが示す型が、各パラメータTypeに対してどのような変性Varianceを持つかを返す
|
||||
|
@ -2166,7 +2152,7 @@ impl Context {
|
|||
{
|
||||
normalize_path(path)
|
||||
} else {
|
||||
todo!("{} {}", path.display(), add.display())
|
||||
todo!("{} // {}", path.display(), add.display())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2423,7 +2409,11 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_gen_t_require_attr_t<'a>(&'a self, gen: &'a GenTypeObj, attr: &str) -> Option<&'a Type> {
|
||||
fn _get_gen_t_require_attr_t<'a>(
|
||||
&'a self,
|
||||
gen: &'a GenTypeObj,
|
||||
attr: &str,
|
||||
) -> Option<&'a Type> {
|
||||
match gen.base_or_sup().map(|req_sup| req_sup.typ()) {
|
||||
Some(Type::Record(rec)) => {
|
||||
if let Some(t) = rec.get(attr) {
|
||||
|
@ -2433,7 +2423,7 @@ impl Context {
|
|||
Some(other) => {
|
||||
let obj = self.rec_get_const_obj(&other.local_name());
|
||||
let obj = option_enum_unwrap!(obj, Some:(ValueObj::Type:(TypeObj::Generated:(_))))?;
|
||||
if let Some(t) = self.get_gen_t_require_attr_t(obj, attr) {
|
||||
if let Some(t) = self._get_gen_t_require_attr_t(obj, attr) {
|
||||
return Some(t);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
1212
crates/erg_compiler/context/instantiate_spec.rs
Normal file
1212
crates/erg_compiler/context/instantiate_spec.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -10,6 +10,7 @@ pub mod hint;
|
|||
pub mod initialize;
|
||||
pub mod inquire;
|
||||
pub mod instantiate;
|
||||
pub mod instantiate_spec;
|
||||
pub mod register;
|
||||
pub mod test;
|
||||
pub mod unify;
|
||||
|
@ -25,7 +26,6 @@ use erg_common::dict::Dict;
|
|||
use erg_common::error::Location;
|
||||
use erg_common::impl_display_from_debug;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
use erg_common::vis::Visibility;
|
||||
use erg_common::Str;
|
||||
use erg_common::{fmt_option, fn_name, get_hash, log};
|
||||
|
||||
|
@ -33,14 +33,14 @@ use ast::{DefId, DefKind, VarName};
|
|||
use erg_parser::ast;
|
||||
use erg_parser::token::Token;
|
||||
|
||||
use crate::context::instantiate::{ConstTemplate, TyVarCache};
|
||||
use crate::context::instantiate::TyVarCache;
|
||||
use crate::context::instantiate_spec::ConstTemplate;
|
||||
use crate::error::{TyCheckError, TyCheckErrors};
|
||||
use crate::module::{SharedCompilerResource, SharedModuleCache};
|
||||
use crate::ty::value::ValueObj;
|
||||
use crate::ty::{Predicate, Type};
|
||||
use crate::ty::{Predicate, Type, Visibility, VisibilityModifier};
|
||||
use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind};
|
||||
use Type::*;
|
||||
use Visibility::*;
|
||||
|
||||
/// For implementing LSP or other IDE features
|
||||
pub trait ContextProvider {
|
||||
|
@ -511,12 +511,30 @@ impl Context {
|
|||
if let Some(name) = param.name {
|
||||
let kind = VarKind::parameter(id, param.is_var_params, param.default_info);
|
||||
let muty = Mutability::from(name);
|
||||
let vi = VarInfo::new(param.t, muty, Private, kind, None, None, None, param.loc);
|
||||
let vi = VarInfo::new(
|
||||
param.t,
|
||||
muty,
|
||||
Visibility::private(name),
|
||||
kind,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
param.loc,
|
||||
);
|
||||
params_.push((Some(VarName::new(Token::static_symbol(name))), vi));
|
||||
} else {
|
||||
let kind = VarKind::parameter(id, param.is_var_params, param.default_info);
|
||||
let muty = Mutability::Immutable;
|
||||
let vi = VarInfo::new(param.t, muty, Private, kind, None, None, None, param.loc);
|
||||
let vi = VarInfo::new(
|
||||
param.t,
|
||||
muty,
|
||||
Visibility::private(name.clone()),
|
||||
kind,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
param.loc,
|
||||
);
|
||||
params_.push((None, vi));
|
||||
}
|
||||
}
|
||||
|
@ -925,7 +943,7 @@ impl Context {
|
|||
&mut self,
|
||||
name: &str,
|
||||
kind: ContextKind,
|
||||
vis: Visibility,
|
||||
vis: VisibilityModifier,
|
||||
tv_cache: Option<TyVarCache>,
|
||||
) {
|
||||
let name = if vis.is_public() {
|
||||
|
@ -999,6 +1017,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
/// enumerates all the variables/methods in the current context & super contexts.
|
||||
fn type_dir(&self) -> Vec<(&VarName, &VarInfo)> {
|
||||
let mut vars: Vec<_> = self
|
||||
.locals
|
||||
|
|
|
@ -11,7 +11,7 @@ use erg_common::levenshtein::get_similar_name;
|
|||
use erg_common::python_util::BUILTIN_PYTHON_MODS;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
use erg_common::vis::Visibility;
|
||||
use erg_common::triple::Triple;
|
||||
use erg_common::Str;
|
||||
use erg_common::{enum_unwrap, get_hash, log, set};
|
||||
|
||||
|
@ -23,7 +23,7 @@ use crate::ty::constructors::{
|
|||
};
|
||||
use crate::ty::free::{Constraint, FreeKind, HasLevel};
|
||||
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||
use crate::ty::{HasType, ParamTy, SubrType, Type};
|
||||
use crate::ty::{HasType, ParamTy, SubrType, Type, Visibility};
|
||||
|
||||
use crate::build_hir::HIRBuilder;
|
||||
use crate::context::{
|
||||
|
@ -38,9 +38,9 @@ use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind};
|
|||
use crate::{feature_error, hir};
|
||||
use Mutability::*;
|
||||
use RegistrationMode::*;
|
||||
use Visibility::*;
|
||||
|
||||
use super::instantiate::{ParamKind, TyVarCache};
|
||||
use super::instantiate::TyVarCache;
|
||||
use super::instantiate_spec::ParamKind;
|
||||
|
||||
/// format:
|
||||
/// ```python
|
||||
|
@ -133,7 +133,7 @@ impl Context {
|
|||
}
|
||||
other => unreachable!("{other}"),
|
||||
};
|
||||
let vis = ident.vis();
|
||||
let vis = self.instantiate_vis_modifier(&ident.vis)?;
|
||||
let kind = id.map_or(VarKind::Declared, VarKind::Defined);
|
||||
let sig_t = self.instantiate_var_sig_t(sig.t_spec.as_ref(), PreRegister)?;
|
||||
let py_name = if let ContextKind::PatchMethodDefs(_base) = &self.kind {
|
||||
|
@ -153,7 +153,7 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
sig_t,
|
||||
muty,
|
||||
vis,
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
kind,
|
||||
None,
|
||||
self.impl_of(),
|
||||
|
@ -172,7 +172,7 @@ impl Context {
|
|||
id: Option<DefId>,
|
||||
) -> TyCheckResult<()> {
|
||||
let name = sig.ident.inspect();
|
||||
let vis = sig.ident.vis();
|
||||
let vis = self.instantiate_vis_modifier(&sig.ident.vis)?;
|
||||
let muty = Mutability::from(&name[..]);
|
||||
let kind = id.map_or(VarKind::Declared, VarKind::Defined);
|
||||
let comptime_decos = sig
|
||||
|
@ -199,7 +199,7 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
t,
|
||||
muty,
|
||||
vis,
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
kind,
|
||||
Some(comptime_decos),
|
||||
self.impl_of(),
|
||||
|
@ -238,18 +238,19 @@ impl Context {
|
|||
ast::VarPattern::Discard(_) => {
|
||||
return Ok(VarInfo {
|
||||
t: body_t.clone(),
|
||||
..VarInfo::const_default()
|
||||
..VarInfo::const_default_private()
|
||||
});
|
||||
}
|
||||
_ => todo!(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let vis = self.instantiate_vis_modifier(&ident.vis)?;
|
||||
// already defined as const
|
||||
if sig.is_const() {
|
||||
let vi = self.decls.remove(ident.inspect()).unwrap_or_else(|| {
|
||||
VarInfo::new(
|
||||
body_t.clone(),
|
||||
Mutability::Const,
|
||||
sig.vis(),
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
VarKind::Declared,
|
||||
None,
|
||||
self.impl_of(),
|
||||
|
@ -270,7 +271,6 @@ impl Context {
|
|||
} else {
|
||||
py_name
|
||||
};
|
||||
let vis = ident.vis();
|
||||
let kind = if id.0 == 0 {
|
||||
VarKind::Declared
|
||||
} else {
|
||||
|
@ -279,14 +279,14 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
body_t.clone(),
|
||||
muty,
|
||||
vis,
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
kind,
|
||||
None,
|
||||
self.impl_of(),
|
||||
py_name,
|
||||
self.absolutize(ident.name.loc()),
|
||||
);
|
||||
log!(info "Registered {}::{}: {}", self.name, ident.name, vi);
|
||||
log!(info "Registered {}{}: {}", self.name, ident, vi);
|
||||
self.locals.insert(ident.name.clone(), vi.clone());
|
||||
Ok(vi)
|
||||
}
|
||||
|
@ -300,9 +300,9 @@ impl Context {
|
|||
kind: ParamKind,
|
||||
) -> TyCheckResult<()> {
|
||||
let vis = if cfg!(feature = "py_compatible") {
|
||||
Public
|
||||
Visibility::BUILTIN_PUBLIC
|
||||
} else {
|
||||
Private
|
||||
Visibility::private(self.name.clone())
|
||||
};
|
||||
let default = kind.default_info();
|
||||
let is_var_params = kind.is_var_params();
|
||||
|
@ -622,6 +622,7 @@ impl Context {
|
|||
self.locals.insert(sig.ident.name.clone(), vi.clone());
|
||||
return Ok(vi);
|
||||
}
|
||||
let vis = self.instantiate_vis_modifier(&sig.ident.vis)?;
|
||||
let muty = if sig.ident.is_const() {
|
||||
Mutability::Const
|
||||
} else {
|
||||
|
@ -717,7 +718,7 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
found_t,
|
||||
muty,
|
||||
sig.ident.vis(),
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
VarKind::Defined(id),
|
||||
Some(comptime_decos),
|
||||
self.impl_of(),
|
||||
|
@ -746,6 +747,7 @@ impl Context {
|
|||
return Ok(());
|
||||
}
|
||||
}
|
||||
let vis = self.instantiate_vis_modifier(&ident.vis)?;
|
||||
let muty = if ident.is_const() {
|
||||
Mutability::Const
|
||||
} else {
|
||||
|
@ -765,7 +767,7 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
failure_t,
|
||||
muty,
|
||||
ident.vis(),
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
VarKind::DoesNotExist,
|
||||
Some(comptime_decos),
|
||||
self.impl_of(),
|
||||
|
@ -814,7 +816,7 @@ impl Context {
|
|||
ast::Signature::Subr(sig) => {
|
||||
if sig.is_const() {
|
||||
let tv_cache = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
|
||||
let vis = def.sig.vis();
|
||||
let vis = self.instantiate_vis_modifier(sig.vis())?;
|
||||
self.grow(__name__, ContextKind::Proc, vis, Some(tv_cache));
|
||||
let (obj, const_t) = match self.eval_const_block(&def.body.block) {
|
||||
Ok(obj) => (obj.clone(), v_enum(set! {obj})),
|
||||
|
@ -852,7 +854,8 @@ impl Context {
|
|||
ast::Signature::Var(sig) => {
|
||||
if sig.is_const() {
|
||||
let kind = ContextKind::from(def.def_kind());
|
||||
self.grow(__name__, kind, sig.vis(), None);
|
||||
let vis = self.instantiate_vis_modifier(sig.vis())?;
|
||||
self.grow(__name__, kind, vis, None);
|
||||
let (obj, const_t) = match self.eval_const_block(&def.body.block) {
|
||||
Ok(obj) => (obj.clone(), v_enum(set! {obj})),
|
||||
Err(errs) => {
|
||||
|
@ -1048,7 +1051,8 @@ impl Context {
|
|||
ident: &Identifier,
|
||||
obj: ValueObj,
|
||||
) -> CompileResult<()> {
|
||||
if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() {
|
||||
let vis = self.instantiate_vis_modifier(&ident.vis)?;
|
||||
if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() {
|
||||
Err(CompileErrors::from(CompileError::reassign_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1068,7 +1072,7 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
v_enum(set! {other.clone()}),
|
||||
Const,
|
||||
ident.vis(),
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
VarKind::Defined(id),
|
||||
None,
|
||||
self.impl_of(),
|
||||
|
@ -1111,6 +1115,7 @@ impl Context {
|
|||
field.clone(),
|
||||
t.clone(),
|
||||
self.impl_of(),
|
||||
ctx.name.clone(),
|
||||
);
|
||||
ctx.decls.insert(varname, vi);
|
||||
}
|
||||
|
@ -1120,7 +1125,7 @@ impl Context {
|
|||
"base",
|
||||
other.typ().clone(),
|
||||
Immutable,
|
||||
Private,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
None,
|
||||
)?;
|
||||
}
|
||||
|
@ -1133,12 +1138,18 @@ impl Context {
|
|||
"__new__",
|
||||
new_t.clone(),
|
||||
Immutable,
|
||||
Private,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Some("__call__".into()),
|
||||
)?;
|
||||
// 必要なら、ユーザーが独自に上書きする
|
||||
// users can override this if necessary
|
||||
methods.register_auto_impl("new", new_t, Immutable, Public, None)?;
|
||||
methods.register_auto_impl(
|
||||
"new",
|
||||
new_t,
|
||||
Immutable,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
None,
|
||||
)?;
|
||||
ctx.methods_list
|
||||
.push((ClassDefType::Simple(gen.typ().clone()), methods));
|
||||
self.register_gen_mono_type(ident, gen, ctx, Const)
|
||||
|
@ -1189,6 +1200,7 @@ impl Context {
|
|||
field.clone(),
|
||||
t.clone(),
|
||||
self.impl_of(),
|
||||
ctx.name.clone(),
|
||||
);
|
||||
ctx.decls.insert(varname, vi);
|
||||
}
|
||||
|
@ -1202,11 +1214,17 @@ impl Context {
|
|||
"__new__",
|
||||
new_t.clone(),
|
||||
Immutable,
|
||||
Private,
|
||||
Visibility::BUILTIN_PRIVATE,
|
||||
Some("__call__".into()),
|
||||
)?;
|
||||
// 必要なら、ユーザーが独自に上書きする
|
||||
methods.register_auto_impl("new", new_t, Immutable, Public, None)?;
|
||||
methods.register_auto_impl(
|
||||
"new",
|
||||
new_t,
|
||||
Immutable,
|
||||
Visibility::BUILTIN_PUBLIC,
|
||||
None,
|
||||
)?;
|
||||
ctx.methods_list
|
||||
.push((ClassDefType::Simple(gen.typ().clone()), methods));
|
||||
self.register_gen_mono_type(ident, gen, ctx, Const)
|
||||
|
@ -1242,7 +1260,12 @@ impl Context {
|
|||
);
|
||||
let Some(TypeObj::Builtin(Type::Record(req))) = gen.base_or_sup() else { todo!("{gen}") };
|
||||
for (field, t) in req.iter() {
|
||||
let vi = VarInfo::instance_attr(field.clone(), t.clone(), self.impl_of());
|
||||
let vi = VarInfo::instance_attr(
|
||||
field.clone(),
|
||||
t.clone(),
|
||||
self.impl_of(),
|
||||
ctx.name.clone(),
|
||||
);
|
||||
ctx.decls
|
||||
.insert(VarName::from_str(field.symbol.clone()), vi);
|
||||
}
|
||||
|
@ -1273,8 +1296,12 @@ impl Context {
|
|||
);
|
||||
if let Some(additional) = additional {
|
||||
for (field, t) in additional.iter() {
|
||||
let vi =
|
||||
VarInfo::instance_attr(field.clone(), t.clone(), self.impl_of());
|
||||
let vi = VarInfo::instance_attr(
|
||||
field.clone(),
|
||||
t.clone(),
|
||||
self.impl_of(),
|
||||
ctx.name.clone(),
|
||||
);
|
||||
ctx.decls
|
||||
.insert(VarName::from_str(field.symbol.clone()), vi);
|
||||
}
|
||||
|
@ -1330,6 +1357,7 @@ impl Context {
|
|||
}
|
||||
|
||||
pub(crate) fn register_type_alias(&mut self, ident: &Identifier, t: Type) -> CompileResult<()> {
|
||||
let vis = self.instantiate_vis_modifier(&ident.vis)?;
|
||||
if self.mono_types.contains_key(ident.inspect()) {
|
||||
Err(CompileErrors::from(CompileError::reassign_error(
|
||||
self.cfg.input.clone(),
|
||||
|
@ -1338,7 +1366,7 @@ impl Context {
|
|||
self.caused_by(),
|
||||
ident.inspect(),
|
||||
)))
|
||||
} else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() {
|
||||
} else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() {
|
||||
// TODO: display where defined
|
||||
Err(CompileErrors::from(CompileError::reassign_error(
|
||||
self.cfg.input.clone(),
|
||||
|
@ -1354,7 +1382,7 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
Type::Type,
|
||||
muty,
|
||||
ident.vis(),
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
VarKind::Defined(id),
|
||||
None,
|
||||
self.impl_of(),
|
||||
|
@ -1376,6 +1404,7 @@ impl Context {
|
|||
ctx: Self,
|
||||
muty: Mutability,
|
||||
) -> CompileResult<()> {
|
||||
let vis = self.instantiate_vis_modifier(&ident.vis)?;
|
||||
// FIXME: recursive search
|
||||
if self.mono_types.contains_key(ident.inspect()) {
|
||||
Err(CompileErrors::from(CompileError::reassign_error(
|
||||
|
@ -1385,7 +1414,7 @@ impl Context {
|
|||
self.caused_by(),
|
||||
ident.inspect(),
|
||||
)))
|
||||
} else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() {
|
||||
} else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() {
|
||||
Err(CompileErrors::from(CompileError::reassign_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1401,7 +1430,7 @@ impl Context {
|
|||
let vi = VarInfo::new(
|
||||
meta_t,
|
||||
muty,
|
||||
ident.vis(),
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
VarKind::Defined(id),
|
||||
None,
|
||||
self.impl_of(),
|
||||
|
@ -1454,6 +1483,7 @@ impl Context {
|
|||
ctx: Self,
|
||||
muty: Mutability,
|
||||
) -> CompileResult<()> {
|
||||
let vis = self.instantiate_vis_modifier(&ident.vis)?;
|
||||
// FIXME: recursive search
|
||||
if self.patches.contains_key(ident.inspect()) {
|
||||
Err(CompileErrors::from(CompileError::reassign_error(
|
||||
|
@ -1463,7 +1493,7 @@ impl Context {
|
|||
self.caused_by(),
|
||||
ident.inspect(),
|
||||
)))
|
||||
} else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() {
|
||||
} else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() {
|
||||
Err(CompileErrors::from(CompileError::reassign_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1481,7 +1511,7 @@ impl Context {
|
|||
VarInfo::new(
|
||||
meta_t,
|
||||
muty,
|
||||
ident.vis(),
|
||||
Visibility::new(vis, self.name.clone()),
|
||||
VarKind::Defined(id),
|
||||
None,
|
||||
self.impl_of(),
|
||||
|
@ -1758,7 +1788,7 @@ impl Context {
|
|||
)))
|
||||
} else if self.locals.get(ident.inspect()).is_some() {
|
||||
let vi = self.locals.remove(ident.inspect()).unwrap();
|
||||
self.deleted_locals.insert(ident.name.clone(), vi);
|
||||
self.deleted_locals.insert(ident.raw.name.clone(), vi);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(TyCheckErrors::from(TyCheckError::no_var_error(
|
||||
|
@ -1831,7 +1861,7 @@ impl Context {
|
|||
#[allow(clippy::single_match)]
|
||||
match acc {
|
||||
hir::Accessor::Ident(ident) => {
|
||||
if let Some(vi) = self.get_mut_current_scope_var(&ident.name) {
|
||||
if let Some(vi) = self.get_mut_current_scope_var(&ident.raw.name) {
|
||||
vi.t = t;
|
||||
} else {
|
||||
return Err(TyCheckErrors::from(TyCheckError::feature_error(
|
||||
|
@ -1850,22 +1880,22 @@ impl Context {
|
|||
}
|
||||
|
||||
pub(crate) fn inc_ref_simple_typespec(&self, simple: &SimpleTypeSpec) {
|
||||
if let Ok(vi) = self.rec_get_var_info(
|
||||
if let Triple::Ok(vi) = self.rec_get_var_info(
|
||||
&simple.ident,
|
||||
crate::compile::AccessKind::Name,
|
||||
&self.cfg.input,
|
||||
&self.name,
|
||||
self,
|
||||
) {
|
||||
self.inc_ref(&vi, &simple.ident.name);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn inc_ref_const_local(&self, local: &ConstIdentifier) {
|
||||
if let Ok(vi) = self.rec_get_var_info(
|
||||
if let Triple::Ok(vi) = self.rec_get_var_info(
|
||||
local,
|
||||
crate::compile::AccessKind::Name,
|
||||
&self.cfg.input,
|
||||
&self.name,
|
||||
self,
|
||||
) {
|
||||
self.inc_ref(&vi, &local.name);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::lower::ASTLowerer;
|
|||
use crate::ty::constructors::mono;
|
||||
use crate::ty::free::HasLevel;
|
||||
use crate::ty::value::{GenTypeObj, TypeObj};
|
||||
use crate::ty::{HasType, Type};
|
||||
use crate::ty::{HasType, Type, Visibility};
|
||||
|
||||
use crate::compile::AccessKind;
|
||||
use crate::context::RegistrationMode;
|
||||
|
@ -73,7 +73,7 @@ impl ASTLowerer {
|
|||
.assign_var_sig(&sig, found_body_t, id, py_name.clone())?;
|
||||
}
|
||||
// FIXME: Identifier::new should be used
|
||||
let mut ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone());
|
||||
let mut ident = hir::Identifier::bare(ident.clone());
|
||||
ident.vi.t = found_body_t.clone();
|
||||
ident.vi.py_name = py_name;
|
||||
let sig = hir::VarSignature::new(ident, sig.t_spec);
|
||||
|
@ -127,20 +127,15 @@ impl ASTLowerer {
|
|||
let vi = self
|
||||
.module
|
||||
.context
|
||||
.rec_get_var_info(
|
||||
&ident,
|
||||
AccessKind::Name,
|
||||
self.input(),
|
||||
&self.module.context.name,
|
||||
)
|
||||
.rec_get_var_info(&ident, AccessKind::Name, self.input(), &self.module.context)
|
||||
.unwrap_or(VarInfo::default());
|
||||
let ident = hir::Identifier::new(ident.dot, ident.name, None, vi);
|
||||
let ident = hir::Identifier::new(ident, None, vi);
|
||||
let acc = hir::Accessor::Ident(ident);
|
||||
Ok(acc)
|
||||
}
|
||||
ast::Accessor::Attr(attr) => {
|
||||
let obj = self.fake_lower_expr(*attr.obj)?;
|
||||
let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name);
|
||||
let ident = hir::Identifier::bare(attr.ident);
|
||||
Ok(obj.attr(ident))
|
||||
}
|
||||
other => Err(LowerErrors::from(LowerError::declare_error(
|
||||
|
@ -177,9 +172,7 @@ impl ASTLowerer {
|
|||
|
||||
fn fake_lower_call(&self, call: ast::Call) -> LowerResult<hir::Call> {
|
||||
let obj = self.fake_lower_expr(*call.obj)?;
|
||||
let attr_name = call
|
||||
.attr_name
|
||||
.map(|ident| hir::Identifier::bare(ident.dot, ident.name));
|
||||
let attr_name = call.attr_name.map(hir::Identifier::bare);
|
||||
let args = self.fake_lower_args(call.args)?;
|
||||
Ok(hir::Call::new(obj, attr_name, args))
|
||||
}
|
||||
|
@ -247,12 +240,12 @@ impl ASTLowerer {
|
|||
match sig {
|
||||
ast::Signature::Var(var) => {
|
||||
let ident = var.ident().unwrap().clone();
|
||||
let ident = hir::Identifier::bare(ident.dot, ident.name);
|
||||
let ident = hir::Identifier::bare(ident);
|
||||
let sig = hir::VarSignature::new(ident, var.t_spec);
|
||||
Ok(hir::Signature::Var(sig))
|
||||
}
|
||||
ast::Signature::Subr(subr) => {
|
||||
let ident = hir::Identifier::bare(subr.ident.dot, subr.ident.name);
|
||||
let ident = hir::Identifier::bare(subr.ident);
|
||||
let params = self.fake_lower_params(subr.params)?;
|
||||
let sig = hir::SubrSignature::new(ident, subr.bounds, params, subr.return_t_spec);
|
||||
Ok(hir::Signature::Subr(sig))
|
||||
|
@ -454,19 +447,19 @@ impl ASTLowerer {
|
|||
self.declare_subtype(&ident, &t)?;
|
||||
}
|
||||
let muty = Mutability::from(&ident.inspect()[..]);
|
||||
let vis = ident.vis();
|
||||
let vis = self.module.context.instantiate_vis_modifier(&ident.vis)?;
|
||||
let py_name = Str::rc(ident.inspect().trim_end_matches('!'));
|
||||
let vi = VarInfo::new(
|
||||
t,
|
||||
muty,
|
||||
vis,
|
||||
Visibility::new(vis, self.module.context.name.clone()),
|
||||
VarKind::Declared,
|
||||
None,
|
||||
None,
|
||||
Some(py_name),
|
||||
self.module.context.absolutize(ident.loc()),
|
||||
);
|
||||
let ident = hir::Identifier::new(ident.dot, ident.name, None, vi);
|
||||
let ident = hir::Identifier::new(ident, None, vi);
|
||||
let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr)?;
|
||||
let t_spec = hir::TypeSpecWithOp::new(
|
||||
tasc.t_spec.op,
|
||||
|
@ -488,11 +481,10 @@ impl ASTLowerer {
|
|||
RegistrationMode::Normal,
|
||||
false,
|
||||
)?;
|
||||
let namespace = self.module.context.name.clone();
|
||||
let ctx = self
|
||||
.module
|
||||
.context
|
||||
.get_mut_singular_ctx(attr.obj.as_ref(), &namespace)?;
|
||||
.get_mut_singular_ctx(attr.obj.as_ref(), &self.module.context.name.clone())?;
|
||||
ctx.assign_var_sig(
|
||||
&ast::VarSignature::new(ast::VarPattern::Ident(attr.ident.clone()), None),
|
||||
&t,
|
||||
|
@ -501,19 +493,22 @@ impl ASTLowerer {
|
|||
)?;
|
||||
let obj = self.fake_lower_expr(*attr.obj)?;
|
||||
let muty = Mutability::from(&attr.ident.inspect()[..]);
|
||||
let vis = attr.ident.vis();
|
||||
let vis = self
|
||||
.module
|
||||
.context
|
||||
.instantiate_vis_modifier(&attr.ident.vis)?;
|
||||
let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!'));
|
||||
let vi = VarInfo::new(
|
||||
t,
|
||||
muty,
|
||||
vis,
|
||||
Visibility::new(vis, self.module.context.name.clone()),
|
||||
VarKind::Declared,
|
||||
None,
|
||||
None,
|
||||
Some(py_name),
|
||||
self.module.context.absolutize(attr.ident.loc()),
|
||||
);
|
||||
let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi);
|
||||
let ident = hir::Identifier::new(attr.ident, None, vi);
|
||||
let attr = obj.attr_expr(ident);
|
||||
let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr)?;
|
||||
let t_spec = hir::TypeSpecWithOp::new(
|
||||
|
@ -544,10 +539,11 @@ impl ASTLowerer {
|
|||
return Ok(());
|
||||
}
|
||||
if ident.is_const() {
|
||||
let vis = self.module.context.instantiate_vis_modifier(&ident.vis)?;
|
||||
let vi = VarInfo::new(
|
||||
t.clone(),
|
||||
Mutability::Const,
|
||||
ident.vis(),
|
||||
Visibility::new(vis, self.module.context.name.clone()),
|
||||
VarKind::Declared,
|
||||
None,
|
||||
None,
|
||||
|
|
|
@ -5,15 +5,12 @@
|
|||
use erg_common::config::ErgConfig;
|
||||
use erg_common::log;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
use erg_common::vis::Visibility;
|
||||
use erg_common::Str;
|
||||
use erg_parser::token::TokenKind;
|
||||
use Visibility::*;
|
||||
|
||||
use crate::ty::HasType;
|
||||
|
||||
use crate::error::{EffectError, EffectErrors};
|
||||
use crate::hir::{Array, Def, Dict, Expr, Params, Set, Signature, Tuple, HIR};
|
||||
use crate::ty::{HasType, Visibility};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
enum BlockKind {
|
||||
|
@ -36,7 +33,7 @@ use BlockKind::*;
|
|||
#[derive(Debug)]
|
||||
pub struct SideEffectChecker {
|
||||
cfg: ErgConfig,
|
||||
path_stack: Vec<(Str, Visibility)>,
|
||||
path_stack: Vec<Visibility>,
|
||||
block_stack: Vec<BlockKind>,
|
||||
errs: EffectErrors,
|
||||
}
|
||||
|
@ -52,13 +49,11 @@ impl SideEffectChecker {
|
|||
}
|
||||
|
||||
fn full_path(&self) -> String {
|
||||
self.path_stack
|
||||
.iter()
|
||||
.fold(String::new(), |acc, (path, vis)| {
|
||||
self.path_stack.iter().fold(String::new(), |acc, vis| {
|
||||
if vis.is_public() {
|
||||
acc + "." + &path[..]
|
||||
acc + "." + &vis.def_namespace[..]
|
||||
} else {
|
||||
acc + "::" + &path[..]
|
||||
acc + "::" + &vis.def_namespace[..]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -85,7 +80,7 @@ impl SideEffectChecker {
|
|||
}
|
||||
|
||||
pub fn check(mut self, hir: HIR) -> Result<HIR, (HIR, EffectErrors)> {
|
||||
self.path_stack.push((hir.name.clone(), Private));
|
||||
self.path_stack.push(Visibility::private(hir.name.clone()));
|
||||
self.block_stack.push(Module);
|
||||
log!(info "the side-effects checking process has started.{RESET}");
|
||||
// At the top level, there is no problem with side effects, only check for purity violations.
|
||||
|
@ -150,7 +145,8 @@ impl SideEffectChecker {
|
|||
}
|
||||
},
|
||||
Expr::Record(rec) => {
|
||||
self.path_stack.push((Str::ever("<record>"), Private));
|
||||
self.path_stack
|
||||
.push(Visibility::private(Str::ever("<record>")));
|
||||
self.block_stack.push(Instant);
|
||||
for attr in rec.attrs.iter() {
|
||||
self.check_def(attr);
|
||||
|
@ -184,10 +180,12 @@ impl SideEffectChecker {
|
|||
Expr::Lambda(lambda) => {
|
||||
let is_proc = lambda.is_procedural();
|
||||
if is_proc {
|
||||
self.path_stack.push((Str::ever("<lambda!>"), Private));
|
||||
self.path_stack
|
||||
.push(Visibility::private(Str::ever("<lambda!>")));
|
||||
self.block_stack.push(Proc);
|
||||
} else {
|
||||
self.path_stack.push((Str::ever("<lambda>"), Private));
|
||||
self.path_stack
|
||||
.push(Visibility::private(Str::ever("<lambda>")));
|
||||
self.block_stack.push(Func);
|
||||
}
|
||||
lambda.body.iter().for_each(|chunk| self.check_expr(chunk));
|
||||
|
@ -244,10 +242,7 @@ impl SideEffectChecker {
|
|||
}
|
||||
|
||||
fn check_def(&mut self, def: &Def) {
|
||||
let name_and_vis = match &def.sig {
|
||||
Signature::Var(var) => (var.inspect().clone(), var.vis()),
|
||||
Signature::Subr(subr) => (subr.ident.inspect().clone(), subr.ident.vis()),
|
||||
};
|
||||
let name_and_vis = Visibility::new(def.sig.vis().clone(), def.sig.inspect().clone());
|
||||
self.path_stack.push(name_and_vis);
|
||||
let is_procedural = def.sig.is_procedural();
|
||||
let is_subr = def.sig.is_subr();
|
||||
|
@ -360,7 +355,8 @@ impl SideEffectChecker {
|
|||
}
|
||||
},
|
||||
Expr::Record(record) => {
|
||||
self.path_stack.push((Str::ever("<record>"), Private));
|
||||
self.path_stack
|
||||
.push(Visibility::private(Str::ever("<record>")));
|
||||
self.block_stack.push(Instant);
|
||||
for attr in record.attrs.iter() {
|
||||
self.check_def(attr);
|
||||
|
@ -433,10 +429,12 @@ impl SideEffectChecker {
|
|||
Expr::Lambda(lambda) => {
|
||||
let is_proc = lambda.is_procedural();
|
||||
if is_proc {
|
||||
self.path_stack.push((Str::ever("<lambda!>"), Private));
|
||||
self.path_stack
|
||||
.push(Visibility::private(Str::ever("<lambda!>")));
|
||||
self.block_stack.push(Proc);
|
||||
} else {
|
||||
self.path_stack.push((Str::ever("<lambda>"), Private));
|
||||
self.path_stack
|
||||
.push(Visibility::private(Str::ever("<lambda>")));
|
||||
self.block_stack.push(Func);
|
||||
}
|
||||
self.check_params(&lambda.params);
|
||||
|
|
|
@ -2,12 +2,12 @@ use erg_common::config::Input;
|
|||
use erg_common::error::{ErrorCore, ErrorKind::*, Location, SubMessage};
|
||||
use erg_common::style::{StyledStr, StyledString, StyledStrings, Stylize};
|
||||
use erg_common::traits::Locational;
|
||||
use erg_common::vis::Visibility;
|
||||
use erg_common::{switch_lang, Str};
|
||||
|
||||
use crate::error::*;
|
||||
use crate::hir::{Expr, Identifier};
|
||||
use crate::ty::{HasType, Type};
|
||||
use crate::ty::{HasType, Type, Visibility};
|
||||
use crate::varinfo::VarInfo;
|
||||
|
||||
pub type LowerError = CompileError;
|
||||
pub type LowerWarning = LowerError;
|
||||
|
@ -196,7 +196,47 @@ impl LowerError {
|
|||
"english" => format!("exists a similar name variable: {n}"),
|
||||
)
|
||||
});
|
||||
let found = StyledString::new(name, Some(ERR), Some(ATTR));
|
||||
let found = name.with_color_and_attr(ERR, ATTR);
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
switch_lang!(
|
||||
"japanese" => format!("{found}という変数は定義されていません"),
|
||||
"simplified_chinese" => format!("{found}未定义"),
|
||||
"traditional_chinese" => format!("{found}未定義"),
|
||||
"english" => format!("{found} is not defined"),
|
||||
),
|
||||
errno,
|
||||
NameError,
|
||||
loc,
|
||||
),
|
||||
input,
|
||||
caused_by,
|
||||
)
|
||||
}
|
||||
|
||||
/// TODO: replace `no_var_error` with this function
|
||||
pub fn detailed_no_var_error(
|
||||
input: Input,
|
||||
errno: usize,
|
||||
loc: Location,
|
||||
caused_by: String,
|
||||
name: &str,
|
||||
similar_name: Option<&str>,
|
||||
similar_info: Option<&VarInfo>,
|
||||
) -> Self {
|
||||
let name = readable_name(name);
|
||||
let hint = similar_name.map(|n| {
|
||||
let vis = similar_info.map_or("".into(), |vi| vi.vis.modifier.display());
|
||||
let n = n.with_color_and_attr(HINT, ATTR);
|
||||
switch_lang!(
|
||||
"japanese" => format!("似た名前の{vis}変数があります: {n}"),
|
||||
"simplified_chinese" => format!("存在相同名称{vis}变量: {n}"),
|
||||
"traditional_chinese" => format!("存在相同名稱{vis}變量: {n}"),
|
||||
"english" => format!("exists a similar name {vis} variable: {n}"),
|
||||
)
|
||||
});
|
||||
let found = name.with_color_and_attr(ERR, ATTR);
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
|
@ -226,7 +266,7 @@ impl LowerError {
|
|||
) -> Self {
|
||||
let name = readable_name(name);
|
||||
let hint = similar_name.map(|n| {
|
||||
let n = StyledStr::new(n, Some(HINT), Some(ATTR));
|
||||
let n = n.with_color_and_attr(HINT, ATTR);
|
||||
switch_lang!(
|
||||
"japanese" => format!("似た名前の変数があります: {n}"),
|
||||
"simplified_chinese" => format!("存在相同名称变量: {n}"),
|
||||
|
@ -234,7 +274,7 @@ impl LowerError {
|
|||
"english" => format!("exists a similar name variable: {n}"),
|
||||
)
|
||||
});
|
||||
let found = StyledString::new(name, Some(ERR), Some(ATTR));
|
||||
let found = name.with_color_and_attr(ERR, ATTR);
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
|
@ -264,7 +304,7 @@ impl LowerError {
|
|||
) -> Self {
|
||||
let name = readable_name(name);
|
||||
let hint = similar_name.map(|n| {
|
||||
let n = StyledStr::new(n, Some(HINT), Some(ATTR));
|
||||
let n = n.with_color_and_attr(HINT, ATTR);
|
||||
switch_lang!(
|
||||
"japanese" => format!("似た名前の変数があります: {n}"),
|
||||
"simplified_chinese" => format!("存在相同名称变量: {n}"),
|
||||
|
@ -272,7 +312,7 @@ impl LowerError {
|
|||
"english" => format!("exists a similar name variable: {n}"),
|
||||
)
|
||||
});
|
||||
let found = StyledString::new(name, Some(ERR), Some(ATTR));
|
||||
let found = name.with_color_and_attr(ERR, ATTR);
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
|
@ -396,6 +436,45 @@ impl LowerError {
|
|||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn detailed_no_attr_error(
|
||||
input: Input,
|
||||
errno: usize,
|
||||
loc: Location,
|
||||
caused_by: String,
|
||||
obj_t: &Type,
|
||||
name: &str,
|
||||
similar_name: Option<&str>,
|
||||
similar_info: Option<&VarInfo>,
|
||||
) -> Self {
|
||||
let hint = similar_name.map(|n| {
|
||||
let vis = similar_info.map_or("".into(), |vi| vi.vis.modifier.display());
|
||||
switch_lang!(
|
||||
"japanese" => format!("似た名前の{vis}属性があります: {n}"),
|
||||
"simplified_chinese" => format!("具有相同名称的{vis}属性: {n}"),
|
||||
"traditional_chinese" => format!("具有相同名稱的{vis}屬性: {n}"),
|
||||
"english" => format!("has a similar name {vis} attribute: {n}"),
|
||||
)
|
||||
});
|
||||
let found = StyledString::new(name, Some(ERR), Some(ATTR));
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
switch_lang!(
|
||||
"japanese" => format!("{obj_t}型オブジェクトに{found}という属性はありません"),
|
||||
"simplified_chinese" => format!("{obj_t}对象没有属性{found}"),
|
||||
"traditional_chinese" => format!("{obj_t}對像沒有屬性{found}"),
|
||||
"english" => format!("{obj_t} object has no attribute {found}"),
|
||||
),
|
||||
errno,
|
||||
AttributeError,
|
||||
loc,
|
||||
),
|
||||
input,
|
||||
caused_by,
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn singular_no_attr_error(
|
||||
input: Input,
|
||||
|
@ -510,21 +589,7 @@ impl LowerError {
|
|||
name: &str,
|
||||
vis: Visibility,
|
||||
) -> Self {
|
||||
let visibility = if vis.is_private() {
|
||||
switch_lang!(
|
||||
"japanese" => "非公開",
|
||||
"simplified_chinese" => "私有",
|
||||
"traditional_chinese" => "私有",
|
||||
"english" => "private",
|
||||
)
|
||||
} else {
|
||||
switch_lang!(
|
||||
"japanese" => "公開",
|
||||
"simplified_chinese" => "公有",
|
||||
"traditional_chinese" => "公有",
|
||||
"english" => "public",
|
||||
)
|
||||
};
|
||||
let visibility = vis.modifier.display();
|
||||
let found = StyledString::new(readable_name(name), Some(ERR), Some(ATTR));
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
|
|
|
@ -520,7 +520,7 @@ mod test {
|
|||
varinfo::{AbsLocation, VarInfo},
|
||||
};
|
||||
use erg_common::{config::Input, error::Location};
|
||||
use erg_parser::ast::VarName;
|
||||
use erg_parser::ast::{VarName, VisModifierSpec};
|
||||
|
||||
// These Erg codes are not correct grammar.
|
||||
// This test make sure sub_msg and hint are displayed correctly.
|
||||
|
@ -704,19 +704,17 @@ mod test {
|
|||
errors.push(err);
|
||||
|
||||
let input = Input::pipe("ambiguous type error".to_string());
|
||||
let expr = Identifier::new(
|
||||
Some(erg_parser::token::Token {
|
||||
kind: erg_parser::token::TokenKind::EOF,
|
||||
content: "expr_content".into(),
|
||||
lineno: 1,
|
||||
col_begin: 1,
|
||||
}),
|
||||
let raw = erg_parser::ast::Identifier::new(
|
||||
VisModifierSpec::Private,
|
||||
VarName::from_str("variable_name".into()),
|
||||
);
|
||||
let expr = Identifier::new(
|
||||
raw,
|
||||
None,
|
||||
VarInfo::new(
|
||||
Type::Nat,
|
||||
crate::varinfo::Mutability::Const,
|
||||
erg_common::vis::Visibility::Private,
|
||||
crate::ty::Visibility::DUMMY_PRIVATE,
|
||||
crate::varinfo::VarKind::Builtin,
|
||||
None,
|
||||
None,
|
||||
|
@ -759,7 +757,7 @@ mod test {
|
|||
|
||||
let input = Input::pipe("visibility error".to_string());
|
||||
let loc = Location::Line(1);
|
||||
let vis = erg_common::vis::Visibility::Private;
|
||||
let vis = crate::ty::Visibility::DUMMY_PRIVATE;
|
||||
let err =
|
||||
TyCheckError::visibility_error(input, errno, loc, caused_by.to_string(), name, vis);
|
||||
errors.push(err);
|
||||
|
|
|
@ -6,7 +6,6 @@ use erg_common::error::Location;
|
|||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::traits::{Locational, NestedDisplay, NoTypeDisplay, Stream};
|
||||
use erg_common::vis::{Field, Visibility};
|
||||
use erg_common::Str;
|
||||
use erg_common::{
|
||||
enum_unwrap, fmt_option, fmt_vec, impl_display_for_enum, impl_display_from_nested,
|
||||
|
@ -23,7 +22,7 @@ use erg_parser::token::{Token, TokenKind, DOT};
|
|||
use crate::ty::constructors::{array_t, dict_t, set_t, tuple_t};
|
||||
use crate::ty::typaram::TyParam;
|
||||
use crate::ty::value::{GenTypeObj, ValueObj};
|
||||
use crate::ty::{HasType, Type};
|
||||
use crate::ty::{Field, HasType, Type, VisibilityModifier};
|
||||
|
||||
use crate::context::eval::type_from_token_kind;
|
||||
use crate::error::readable_name;
|
||||
|
@ -381,22 +380,14 @@ impl Args {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Identifier {
|
||||
pub dot: Option<Token>,
|
||||
pub name: VarName,
|
||||
pub raw: ast::Identifier,
|
||||
pub qual_name: Option<Str>,
|
||||
pub vi: VarInfo,
|
||||
}
|
||||
|
||||
impl NestedDisplay for Identifier {
|
||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||
match &self.dot {
|
||||
Some(_dot) => {
|
||||
write!(f, ".{}", self.name)?;
|
||||
}
|
||||
None => {
|
||||
write!(f, "::{}", self.name)?;
|
||||
}
|
||||
}
|
||||
write!(f, "{}", self.raw)?;
|
||||
if let Some(qn) = &self.qual_name {
|
||||
write!(f, "(qual_name: {qn})")?;
|
||||
}
|
||||
|
@ -409,10 +400,7 @@ impl NestedDisplay for Identifier {
|
|||
|
||||
impl NoTypeDisplay for Identifier {
|
||||
fn to_string_notype(&self) -> String {
|
||||
match &self.dot {
|
||||
Some(_dot) => format!(".{}", self.name),
|
||||
None => format!("::{}", self.name),
|
||||
}
|
||||
self.raw.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,56 +427,50 @@ impl HasType for Identifier {
|
|||
|
||||
impl Locational for Identifier {
|
||||
fn loc(&self) -> Location {
|
||||
if let Some(dot) = &self.dot {
|
||||
Location::concat(dot, &self.name)
|
||||
} else {
|
||||
self.name.loc()
|
||||
}
|
||||
self.raw.loc()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Identifier> for Field {
|
||||
fn from(ident: &Identifier) -> Self {
|
||||
Self::new(ident.vis(), ident.inspect().clone())
|
||||
Self::new(ident.vis().clone(), ident.inspect().clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Identifier {
|
||||
pub const fn new(
|
||||
dot: Option<Token>,
|
||||
name: VarName,
|
||||
qual_name: Option<Str>,
|
||||
vi: VarInfo,
|
||||
) -> Self {
|
||||
Self {
|
||||
dot,
|
||||
name,
|
||||
qual_name,
|
||||
vi,
|
||||
}
|
||||
pub const fn new(raw: ast::Identifier, qual_name: Option<Str>, vi: VarInfo) -> Self {
|
||||
Self { raw, qual_name, vi }
|
||||
}
|
||||
|
||||
pub fn public(name: &'static str) -> Self {
|
||||
Self::bare(
|
||||
Some(Token::from_str(TokenKind::Dot, ".")),
|
||||
VarName::from_static(name),
|
||||
)
|
||||
let ident = ast::Identifier::public_from_token(
|
||||
Token::from_str(TokenKind::Dot, "."),
|
||||
Token::static_symbol(name),
|
||||
);
|
||||
Self::bare(ident)
|
||||
}
|
||||
|
||||
pub fn private(name: &'static str) -> Self {
|
||||
Self::bare(None, VarName::from_static(name))
|
||||
let ident = ast::Identifier::private_from_token(Token::static_symbol(name));
|
||||
Self::bare(ident)
|
||||
}
|
||||
|
||||
pub fn private_with_line(name: Str, line: u32) -> Self {
|
||||
Self::bare(None, VarName::from_str_and_line(name, line))
|
||||
let ident = ast::Identifier::private_from_token(Token::symbol_with_line(&name, line));
|
||||
Self::bare(ident)
|
||||
}
|
||||
|
||||
pub fn public_with_line(dot: Token, name: Str, line: u32) -> Self {
|
||||
Self::bare(Some(dot), VarName::from_str_and_line(name, line))
|
||||
let ident = ast::Identifier::public_from_token(dot, Token::symbol_with_line(&name, line));
|
||||
Self::bare(ident)
|
||||
}
|
||||
|
||||
pub const fn bare(dot: Option<Token>, name: VarName) -> Self {
|
||||
Self::new(dot, name, None, VarInfo::const_default())
|
||||
pub const fn bare(ident: ast::Identifier) -> Self {
|
||||
if ident.vis.is_public() {
|
||||
Self::new(ident, None, VarInfo::const_default_public())
|
||||
} else {
|
||||
Self::new(ident, None, VarInfo::const_default_private())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_py_api(&self) -> bool {
|
||||
|
@ -496,18 +478,15 @@ impl Identifier {
|
|||
}
|
||||
|
||||
pub fn is_const(&self) -> bool {
|
||||
self.name.is_const()
|
||||
self.raw.is_const()
|
||||
}
|
||||
|
||||
pub const fn vis(&self) -> Visibility {
|
||||
match &self.dot {
|
||||
Some(_) => Visibility::Public,
|
||||
None => Visibility::Private,
|
||||
}
|
||||
pub fn vis(&self) -> &VisibilityModifier {
|
||||
&self.vi.vis.modifier
|
||||
}
|
||||
|
||||
pub const fn inspect(&self) -> &Str {
|
||||
self.name.inspect()
|
||||
self.raw.inspect()
|
||||
}
|
||||
|
||||
/// show dot + name (no qual_name & type)
|
||||
|
@ -516,11 +495,11 @@ impl Identifier {
|
|||
}
|
||||
|
||||
pub fn is_procedural(&self) -> bool {
|
||||
self.name.is_procedural()
|
||||
self.raw.is_procedural()
|
||||
}
|
||||
|
||||
pub fn downcast(self) -> erg_parser::ast::Identifier {
|
||||
erg_parser::ast::Identifier::new(self.dot, self.name)
|
||||
pub fn downcast(self) -> ast::Identifier {
|
||||
self.raw
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,12 +577,20 @@ impl Accessor {
|
|||
Self::Ident(Identifier::public_with_line(DOT, name, line))
|
||||
}
|
||||
|
||||
pub const fn private(name: Token, vi: VarInfo) -> Self {
|
||||
Self::Ident(Identifier::new(None, VarName::new(name), None, vi))
|
||||
pub fn private(name: Token, vi: VarInfo) -> Self {
|
||||
Self::Ident(Identifier::new(
|
||||
ast::Identifier::private_from_token(name),
|
||||
None,
|
||||
vi,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn public(name: Token, vi: VarInfo) -> Self {
|
||||
Self::Ident(Identifier::new(Some(DOT), VarName::new(name), None, vi))
|
||||
Self::Ident(Identifier::new(
|
||||
ast::Identifier::public_from_token(DOT, name),
|
||||
None,
|
||||
vi,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn attr(obj: Expr, ident: Identifier) -> Self {
|
||||
|
@ -655,12 +642,12 @@ impl Accessor {
|
|||
seps.remove(seps.len() - 1)
|
||||
})
|
||||
.or_else(|| {
|
||||
let mut raw_parts = ident.name.inspect().split_with(&["'"]);
|
||||
let mut raw_parts = ident.inspect().split_with(&["'"]);
|
||||
// "'aaa'".split_with(&["'"]) == ["", "aaa", ""]
|
||||
if raw_parts.len() == 3 || raw_parts.len() == 4 {
|
||||
Some(raw_parts.remove(1))
|
||||
} else {
|
||||
Some(ident.name.inspect())
|
||||
Some(ident.inspect())
|
||||
}
|
||||
}),
|
||||
_ => None,
|
||||
|
@ -1580,9 +1567,13 @@ impl VarSignature {
|
|||
self.ident.inspect()
|
||||
}
|
||||
|
||||
pub fn vis(&self) -> Visibility {
|
||||
pub fn vis(&self) -> &VisibilityModifier {
|
||||
self.ident.vis()
|
||||
}
|
||||
|
||||
pub const fn name(&self) -> &VarName {
|
||||
&self.ident.raw.name
|
||||
}
|
||||
}
|
||||
|
||||
/// Once the default_value is set to Some, all subsequent values must be Some
|
||||
|
@ -1864,6 +1855,10 @@ impl SubrSignature {
|
|||
pub fn is_procedural(&self) -> bool {
|
||||
self.ident.is_procedural()
|
||||
}
|
||||
|
||||
pub const fn name(&self) -> &VarName {
|
||||
&self.ident.raw.name
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -1947,13 +1942,20 @@ impl Signature {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn vis(&self) -> Visibility {
|
||||
pub fn vis(&self) -> &VisibilityModifier {
|
||||
match self {
|
||||
Self::Var(v) => v.ident.vis(),
|
||||
Self::Subr(s) => s.ident.vis(),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn inspect(&self) -> &Str {
|
||||
match self {
|
||||
Self::Var(v) => v.ident.inspect(),
|
||||
Self::Subr(s) => s.ident.inspect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn ident(&self) -> &Identifier {
|
||||
match self {
|
||||
Self::Var(v) => &v.ident,
|
||||
|
@ -1975,6 +1977,13 @@ impl Signature {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn name(&self) -> &VarName {
|
||||
match self {
|
||||
Self::Var(v) => v.name(),
|
||||
Self::Subr(s) => s.name(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn t_spec(&self) -> Option<&TypeSpec> {
|
||||
match self {
|
||||
Self::Var(v) => v.t_spec.as_ref(),
|
||||
|
|
|
@ -9,10 +9,10 @@ use erg_common::error::{Location, MultiErrorDisplay};
|
|||
use erg_common::set;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{Locational, NoTypeDisplay, Runnable, Stream};
|
||||
use erg_common::vis::Visibility;
|
||||
use erg_common::triple::Triple;
|
||||
use erg_common::{fmt_option, fn_name, log, option_enum_unwrap, switch_lang, Str};
|
||||
|
||||
use erg_parser::ast;
|
||||
use erg_parser::ast::{self, VisModifierSpec};
|
||||
use erg_parser::ast::{OperationKind, TypeSpecWithOp, VarName, AST};
|
||||
use erg_parser::build_ast::ASTBuilder;
|
||||
use erg_parser::token::{Token, TokenKind};
|
||||
|
@ -27,7 +27,7 @@ use crate::ty::constructors::{
|
|||
use crate::ty::free::Constraint;
|
||||
use crate::ty::typaram::TyParam;
|
||||
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||
use crate::ty::{HasType, ParamTy, Type};
|
||||
use crate::ty::{HasType, ParamTy, Type, VisibilityModifier};
|
||||
|
||||
use crate::context::{
|
||||
ClassDefType, Context, ContextKind, ContextProvider, ModuleContext, RegistrationMode,
|
||||
|
@ -43,7 +43,8 @@ use crate::reorder::Reorderer;
|
|||
use crate::varinfo::{VarInfo, VarKind};
|
||||
use crate::AccessKind;
|
||||
use crate::{feature_error, unreachable_error};
|
||||
use Visibility::*;
|
||||
|
||||
use VisibilityModifier::*;
|
||||
|
||||
/// Checks & infers types of an AST, and convert (lower) it into a HIR
|
||||
#[derive(Debug)]
|
||||
|
@ -624,14 +625,40 @@ impl ASTLowerer {
|
|||
}
|
||||
ast::Accessor::Attr(attr) => {
|
||||
let obj = self.lower_expr(*attr.obj)?;
|
||||
let vi = self.module.context.get_attr_info(
|
||||
let vi = match self.module.context.get_attr_info(
|
||||
&obj,
|
||||
&attr.ident,
|
||||
&self.cfg.input,
|
||||
&self.module.context.name,
|
||||
)?;
|
||||
&self.module.context,
|
||||
) {
|
||||
Triple::Ok(vi) => vi,
|
||||
Triple::Err(errs) => {
|
||||
self.errs.push(errs);
|
||||
VarInfo::ILLEGAL.clone()
|
||||
}
|
||||
Triple::None => {
|
||||
let self_t = obj.t();
|
||||
let (similar_info, similar_name) = self
|
||||
.module
|
||||
.context
|
||||
.get_similar_attr_and_info(&self_t, attr.ident.inspect())
|
||||
.unzip();
|
||||
let err = LowerError::detailed_no_attr_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
attr.ident.loc(),
|
||||
self.module.context.caused_by(),
|
||||
&self_t,
|
||||
attr.ident.inspect(),
|
||||
similar_name,
|
||||
similar_info,
|
||||
);
|
||||
self.errs.push(err);
|
||||
VarInfo::ILLEGAL.clone()
|
||||
}
|
||||
};
|
||||
self.inc_ref(&vi, &attr.ident.name);
|
||||
let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi);
|
||||
let ident = hir::Identifier::new(attr.ident, None, vi);
|
||||
let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident));
|
||||
Ok(acc)
|
||||
}
|
||||
|
@ -649,7 +676,7 @@ impl ASTLowerer {
|
|||
|
||||
fn lower_ident(&mut self, ident: ast::Identifier) -> LowerResult<hir::Identifier> {
|
||||
// `match` is a special form, typing is magic
|
||||
let (vi, __name__) = if ident.vis().is_private()
|
||||
let (vi, __name__) = if ident.vis.is_private()
|
||||
&& (&ident.inspect()[..] == "match" || &ident.inspect()[..] == "match!")
|
||||
{
|
||||
(
|
||||
|
@ -660,22 +687,47 @@ impl ASTLowerer {
|
|||
None,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
self.module.context.rec_get_var_info(
|
||||
let res = match self.module.context.rec_get_var_info(
|
||||
&ident,
|
||||
AccessKind::Name,
|
||||
&self.cfg.input,
|
||||
&self.module.context.name,
|
||||
)?,
|
||||
&self.module.context,
|
||||
) {
|
||||
Triple::Ok(vi) => vi,
|
||||
Triple::Err(err) => {
|
||||
self.errs.push(err);
|
||||
VarInfo::ILLEGAL.clone()
|
||||
}
|
||||
Triple::None => {
|
||||
let (similar_info, similar_name) = self
|
||||
.module
|
||||
.context
|
||||
.get_similar_name_and_info(ident.inspect())
|
||||
.unzip();
|
||||
let err = LowerError::detailed_no_var_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
self.module.context.caused_by(),
|
||||
ident.inspect(),
|
||||
similar_name,
|
||||
similar_info,
|
||||
);
|
||||
self.errs.push(err);
|
||||
VarInfo::ILLEGAL.clone()
|
||||
}
|
||||
};
|
||||
(
|
||||
res,
|
||||
self.module
|
||||
.context
|
||||
.get_singular_ctx_by_ident(&ident, &self.module.context.name)
|
||||
.get_singular_ctx_by_ident(&ident, &self.module.context)
|
||||
.ok()
|
||||
.map(|ctx| ctx.name.clone()),
|
||||
)
|
||||
};
|
||||
self.inc_ref(&vi, &ident.name);
|
||||
let ident = hir::Identifier::new(ident.dot, ident.name, __name__, vi);
|
||||
let ident = hir::Identifier::new(ident, __name__, vi);
|
||||
Ok(ident)
|
||||
}
|
||||
|
||||
|
@ -700,7 +752,7 @@ impl ASTLowerer {
|
|||
let t = self
|
||||
.module
|
||||
.context
|
||||
.get_binop_t(&bin.op, &args, &self.cfg.input, &self.module.context.name)
|
||||
.get_binop_t(&bin.op, &args, &self.cfg.input, &self.module.context)
|
||||
.unwrap_or_else(|errs| {
|
||||
self.errs.extend(errs);
|
||||
VarInfo::ILLEGAL.clone()
|
||||
|
@ -724,7 +776,7 @@ impl ASTLowerer {
|
|||
let t = self
|
||||
.module
|
||||
.context
|
||||
.get_unaryop_t(&unary.op, &args, &self.cfg.input, &self.module.context.name)
|
||||
.get_unaryop_t(&unary.op, &args, &self.cfg.input, &self.module.context)
|
||||
.unwrap_or_else(|errs| {
|
||||
self.errs.extend(errs);
|
||||
VarInfo::ILLEGAL.clone()
|
||||
|
@ -824,7 +876,7 @@ impl ASTLowerer {
|
|||
&hir_args.pos_args,
|
||||
&hir_args.kw_args,
|
||||
&self.cfg.input,
|
||||
&self.module.context.name,
|
||||
&self.module.context,
|
||||
) {
|
||||
Ok(vi) => vi,
|
||||
Err((vi, es)) => {
|
||||
|
@ -835,12 +887,7 @@ impl ASTLowerer {
|
|||
};
|
||||
let attr_name = if let Some(attr_name) = call.attr_name {
|
||||
self.inc_ref(&vi, &attr_name.name);
|
||||
Some(hir::Identifier::new(
|
||||
attr_name.dot,
|
||||
attr_name.name,
|
||||
None,
|
||||
vi,
|
||||
))
|
||||
Some(hir::Identifier::new(attr_name, None, vi))
|
||||
} else {
|
||||
*obj.ref_mut_t() = vi.t;
|
||||
None
|
||||
|
@ -904,17 +951,17 @@ impl ASTLowerer {
|
|||
let args = self.lower_record(pack.args)?;
|
||||
let args = vec![hir::PosArg::new(hir::Expr::Record(args))];
|
||||
let attr_name = ast::Identifier::new(
|
||||
Some(Token::new(
|
||||
VisModifierSpec::Public(Token::new(
|
||||
TokenKind::Dot,
|
||||
Str::ever("."),
|
||||
pack.connector.lineno,
|
||||
pack.connector.col_begin,
|
||||
pack.connector.ln_begin().unwrap(),
|
||||
pack.connector.col_begin().unwrap(),
|
||||
)),
|
||||
ast::VarName::new(Token::new(
|
||||
TokenKind::Symbol,
|
||||
Str::ever("new"),
|
||||
pack.connector.lineno,
|
||||
pack.connector.col_begin,
|
||||
pack.connector.ln_begin().unwrap(),
|
||||
pack.connector.col_begin().unwrap(),
|
||||
)),
|
||||
);
|
||||
let vi = match self.module.context.get_call_t(
|
||||
|
@ -923,7 +970,7 @@ impl ASTLowerer {
|
|||
&args,
|
||||
&[],
|
||||
&self.cfg.input,
|
||||
&self.module.context.name,
|
||||
&self.module.context,
|
||||
) {
|
||||
Ok(vi) => vi,
|
||||
Err((vi, errs)) => {
|
||||
|
@ -932,7 +979,7 @@ impl ASTLowerer {
|
|||
}
|
||||
};
|
||||
let args = hir::Args::pos_only(args, None);
|
||||
let attr_name = hir::Identifier::new(attr_name.dot, attr_name.name, None, vi);
|
||||
let attr_name = hir::Identifier::new(attr_name, None, vi);
|
||||
Ok(hir::Call::new(class, Some(attr_name), args))
|
||||
}
|
||||
|
||||
|
@ -1209,7 +1256,10 @@ impl ASTLowerer {
|
|||
));
|
||||
}
|
||||
let kind = ContextKind::from(def.def_kind());
|
||||
let vis = def.sig.vis();
|
||||
let vis = self
|
||||
.module
|
||||
.context
|
||||
.instantiate_vis_modifier(def.sig.vis())?;
|
||||
let res = match def.sig {
|
||||
ast::Signature::Subr(sig) => {
|
||||
let tv_cache = self
|
||||
|
@ -1263,7 +1313,7 @@ impl ASTLowerer {
|
|||
let ident = match &sig.pat {
|
||||
ast::VarPattern::Ident(ident) => ident.clone(),
|
||||
ast::VarPattern::Discard(token) => {
|
||||
ast::Identifier::new(None, VarName::new(token.clone()))
|
||||
ast::Identifier::private_from_token(token.clone())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
@ -1287,7 +1337,7 @@ impl ASTLowerer {
|
|||
body.id,
|
||||
None,
|
||||
)?;
|
||||
let ident = hir::Identifier::new(ident.dot, ident.name, None, vi);
|
||||
let ident = hir::Identifier::new(ident, None, vi);
|
||||
let sig = hir::VarSignature::new(ident, sig.t_spec);
|
||||
let body = hir::DefBody::new(body.op, block, body.id);
|
||||
Ok(hir::Def::new(hir::Signature::Var(sig), body))
|
||||
|
@ -1358,7 +1408,7 @@ impl ASTLowerer {
|
|||
);
|
||||
self.warns.push(warn);
|
||||
}
|
||||
let ident = hir::Identifier::new(sig.ident.dot, sig.ident.name, None, vi);
|
||||
let ident = hir::Identifier::new(sig.ident, None, vi);
|
||||
let sig =
|
||||
hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
|
||||
let body = hir::DefBody::new(body.op, block, body.id);
|
||||
|
@ -1371,7 +1421,7 @@ impl ASTLowerer {
|
|||
&Type::Failure,
|
||||
)?;
|
||||
self.errs.extend(errs);
|
||||
let ident = hir::Identifier::new(sig.ident.dot, sig.ident.name, None, vi);
|
||||
let ident = hir::Identifier::new(sig.ident, None, vi);
|
||||
let sig =
|
||||
hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
|
||||
let block =
|
||||
|
@ -1396,7 +1446,7 @@ impl ASTLowerer {
|
|||
.unwrap()
|
||||
.fake_subr_assign(&sig.ident, &sig.decorators, Type::Failure)?;
|
||||
let block = self.lower_block(body.block)?;
|
||||
let ident = hir::Identifier::bare(sig.ident.dot, sig.ident.name);
|
||||
let ident = hir::Identifier::bare(sig.ident);
|
||||
let sig = hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
|
||||
let body = hir::DefBody::new(body.op, block, body.id);
|
||||
Ok(hir::Def::new(hir::Signature::Subr(sig), body))
|
||||
|
@ -1439,12 +1489,12 @@ impl ASTLowerer {
|
|||
let kind = ContextKind::MethodDefs(impl_trait.as_ref().map(|(t, _)| t.clone()));
|
||||
self.module
|
||||
.context
|
||||
.grow(&class.local_name(), kind, hir_def.sig.vis(), None);
|
||||
.grow(&class.local_name(), kind, hir_def.sig.vis().clone(), None);
|
||||
for attr in methods.attrs.iter_mut() {
|
||||
match attr {
|
||||
ast::ClassAttr::Def(def) => {
|
||||
if methods.vis.is(TokenKind::Dot) {
|
||||
def.sig.ident_mut().unwrap().dot = Some(Token::new(
|
||||
if methods.vis.is_public() {
|
||||
def.sig.ident_mut().unwrap().vis = VisModifierSpec::Public(Token::new(
|
||||
TokenKind::Dot,
|
||||
".",
|
||||
def.sig.ln_begin().unwrap_or(0),
|
||||
|
@ -1641,14 +1691,17 @@ impl ASTLowerer {
|
|||
let mut hir_methods = hir::Block::empty();
|
||||
for mut methods in class_def.methods_list.into_iter() {
|
||||
let kind = ContextKind::PatchMethodDefs(base_t.clone());
|
||||
self.module
|
||||
.context
|
||||
.grow(hir_def.sig.ident().inspect(), kind, hir_def.sig.vis(), None);
|
||||
self.module.context.grow(
|
||||
hir_def.sig.ident().inspect(),
|
||||
kind,
|
||||
hir_def.sig.vis().clone(),
|
||||
None,
|
||||
);
|
||||
for attr in methods.attrs.iter_mut() {
|
||||
match attr {
|
||||
ast::ClassAttr::Def(def) => {
|
||||
if methods.vis.is(TokenKind::Dot) {
|
||||
def.sig.ident_mut().unwrap().dot = Some(Token::new(
|
||||
if methods.vis.is_public() {
|
||||
def.sig.ident_mut().unwrap().vis = VisModifierSpec::Public(Token::new(
|
||||
TokenKind::Dot,
|
||||
".",
|
||||
def.sig.ln_begin().unwrap(),
|
||||
|
@ -2037,7 +2090,7 @@ impl ASTLowerer {
|
|||
let ctx = self
|
||||
.module
|
||||
.context
|
||||
.get_singular_ctx_by_hir_expr(&expr, &self.module.context.name)?;
|
||||
.get_singular_ctx_by_hir_expr(&expr, &self.module.context)?;
|
||||
// REVIEW: need to use subtype_of?
|
||||
if ctx.super_traits.iter().all(|trait_| trait_ != &spec_t)
|
||||
&& ctx.super_classes.iter().all(|class| class != &spec_t)
|
||||
|
@ -2089,14 +2142,30 @@ impl ASTLowerer {
|
|||
&ident,
|
||||
AccessKind::Name,
|
||||
&self.cfg.input,
|
||||
&self.module.context.name,
|
||||
&self.module.context,
|
||||
)
|
||||
.or_else(|_e| {
|
||||
.none_or_else(|| {
|
||||
self.module.context.rec_get_var_info(
|
||||
&ident,
|
||||
AccessKind::Name,
|
||||
&self.cfg.input,
|
||||
&self.module.context.name,
|
||||
&self.module.context,
|
||||
)
|
||||
})
|
||||
.none_or_result(|| {
|
||||
let (similar_info, similar_name) = self
|
||||
.module
|
||||
.context
|
||||
.get_similar_name_and_info(ident.inspect())
|
||||
.unzip();
|
||||
LowerError::detailed_no_var_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
ident.loc(),
|
||||
self.module.context.caused_by(),
|
||||
ident.inspect(),
|
||||
similar_name,
|
||||
similar_info,
|
||||
)
|
||||
})?;
|
||||
if is_instance_ascription {
|
||||
|
@ -2119,10 +2188,10 @@ impl ASTLowerer {
|
|||
let qual_name = self
|
||||
.module
|
||||
.context
|
||||
.get_singular_ctx_by_ident(&ident, &self.module.context.name)
|
||||
.get_singular_ctx_by_ident(&ident, &self.module.context)
|
||||
.ok()
|
||||
.map(|ctx| ctx.name.clone());
|
||||
let ident = hir::Identifier::new(ident.dot, ident.name, qual_name, ident_vi);
|
||||
let ident = hir::Identifier::new(ident, qual_name, ident_vi);
|
||||
let expr = hir::Expr::Accessor(hir::Accessor::Ident(ident));
|
||||
let t_spec = self.lower_type_spec_with_op(tasc.t_spec, spec_t)?;
|
||||
Ok(expr.type_asc(t_spec))
|
||||
|
|
|
@ -6,13 +6,11 @@ use erg_common::error::Location;
|
|||
use erg_common::set::Set;
|
||||
use erg_common::style::colors::DEBUG_MAIN;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
use erg_common::vis::Visibility;
|
||||
use erg_common::Str;
|
||||
use erg_common::{impl_display_from_debug, log};
|
||||
use erg_parser::ast::{ParamPattern, VarName};
|
||||
use Visibility::*;
|
||||
|
||||
use crate::ty::{HasType, Ownership};
|
||||
use crate::ty::{HasType, Ownership, Visibility};
|
||||
|
||||
use crate::error::{OwnershipError, OwnershipErrors};
|
||||
use crate::hir::{self, Accessor, Array, Block, Def, Expr, Identifier, Signature, Tuple, HIR};
|
||||
|
@ -39,7 +37,7 @@ impl_display_from_debug!(LocalVars);
|
|||
#[derive(Debug)]
|
||||
pub struct OwnershipChecker {
|
||||
cfg: ErgConfig,
|
||||
path_stack: Vec<(Str, Visibility)>,
|
||||
path_stack: Vec<Visibility>,
|
||||
dict: Dict<Str, LocalVars>,
|
||||
errs: OwnershipErrors,
|
||||
}
|
||||
|
@ -55,13 +53,11 @@ impl OwnershipChecker {
|
|||
}
|
||||
|
||||
fn full_path(&self) -> String {
|
||||
self.path_stack
|
||||
.iter()
|
||||
.fold(String::new(), |acc, (path, vis)| {
|
||||
self.path_stack.iter().fold(String::new(), |acc, vis| {
|
||||
if vis.is_public() {
|
||||
acc + "." + &path[..]
|
||||
acc + "." + &vis.def_namespace[..]
|
||||
} else {
|
||||
acc + "::" + &path[..]
|
||||
acc + "::" + &vis.def_namespace[..]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -71,7 +67,7 @@ impl OwnershipChecker {
|
|||
pub fn check(&mut self, hir: HIR) -> Result<HIR, (HIR, OwnershipErrors)> {
|
||||
log!(info "the ownership checking process has started.{RESET}");
|
||||
if self.full_path() != ("::".to_string() + &hir.name[..]) {
|
||||
self.path_stack.push((hir.name.clone(), Private));
|
||||
self.path_stack.push(Visibility::private(hir.name.clone()));
|
||||
self.dict
|
||||
.insert(Str::from(self.full_path()), LocalVars::default());
|
||||
}
|
||||
|
@ -106,7 +102,8 @@ impl OwnershipChecker {
|
|||
Signature::Var(var) => var.inspect().clone(),
|
||||
Signature::Subr(subr) => subr.ident.inspect().clone(),
|
||||
};
|
||||
self.path_stack.push((name, def.sig.vis()));
|
||||
self.path_stack
|
||||
.push(Visibility::new(def.sig.vis().clone(), name));
|
||||
self.dict
|
||||
.insert(Str::from(self.full_path()), LocalVars::default());
|
||||
if let Signature::Subr(subr) = &def.sig {
|
||||
|
@ -247,7 +244,8 @@ impl OwnershipChecker {
|
|||
},
|
||||
// TODO: capturing
|
||||
Expr::Lambda(lambda) => {
|
||||
let name_and_vis = (Str::from(format!("<lambda_{}>", lambda.id)), Private);
|
||||
let name_and_vis =
|
||||
Visibility::private(Str::from(format!("<lambda_{}>", lambda.id)));
|
||||
self.path_stack.push(name_and_vis);
|
||||
self.dict
|
||||
.insert(Str::from(self.full_path()), LocalVars::default());
|
||||
|
@ -289,11 +287,11 @@ impl OwnershipChecker {
|
|||
fn nth_outer_scope(&mut self, n: usize) -> &mut LocalVars {
|
||||
let path = self.path_stack.iter().take(self.path_stack.len() - n).fold(
|
||||
String::new(),
|
||||
|acc, (path, vis)| {
|
||||
|acc, vis| {
|
||||
if vis.is_public() {
|
||||
acc + "." + &path[..]
|
||||
acc + "." + &vis.def_namespace[..]
|
||||
} else {
|
||||
acc + "::" + &path[..]
|
||||
acc + "::" + &vis.def_namespace[..]
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
@ -123,7 +123,6 @@ impl Reorderer {
|
|||
/// ```
|
||||
fn flatten_method_decls(&mut self, new: &mut Vec<Expr>, methods: Methods) {
|
||||
let class = methods.class_as_expr.as_ref();
|
||||
let vis = methods.vis();
|
||||
for method in methods.attrs.into_iter() {
|
||||
match method {
|
||||
ClassAttr::Decl(decl) => {
|
||||
|
@ -138,11 +137,7 @@ impl Reorderer {
|
|||
));
|
||||
continue;
|
||||
};
|
||||
let attr = if vis.is_public() {
|
||||
Identifier::new(Some(methods.vis.clone()), ident.name)
|
||||
} else {
|
||||
Identifier::new(None, ident.name)
|
||||
};
|
||||
let attr = Identifier::new(methods.vis.clone(), ident.name);
|
||||
let expr = class.clone().attr_expr(attr);
|
||||
let decl = TypeAscription::new(expr, decl.t_spec);
|
||||
new.push(Expr::TypeAscription(decl));
|
||||
|
|
|
@ -787,9 +787,9 @@ impl ScriptGenerator {
|
|||
if let Some(py_name) = ident.vi.py_name {
|
||||
return demangle(&py_name);
|
||||
}
|
||||
let name = ident.name.into_token().content.to_string();
|
||||
let name = ident.inspect().to_string();
|
||||
let name = replace_non_symbolic(name);
|
||||
if ident.dot.is_some() {
|
||||
if ident.vis().is_public() {
|
||||
name
|
||||
} else {
|
||||
format!("{name}__")
|
||||
|
@ -941,7 +941,7 @@ impl ScriptGenerator {
|
|||
demangle(&patch_def.sig.ident().to_string_notype()),
|
||||
demangle(&def.sig.ident().to_string_notype()),
|
||||
);
|
||||
def.sig.ident_mut().name = VarName::from_str(Str::from(name));
|
||||
def.sig.ident_mut().raw.name = VarName::from_str(Str::from(name));
|
||||
code += &" ".repeat(self.level);
|
||||
code += &self.transpile_def(def);
|
||||
code.push('\n');
|
||||
|
|
|
@ -11,6 +11,7 @@ pub mod free;
|
|||
pub mod predicate;
|
||||
pub mod typaram;
|
||||
pub mod value;
|
||||
pub mod vis;
|
||||
|
||||
use std::fmt;
|
||||
use std::ops::{BitAnd, BitOr, Deref, Not, Range, RangeInclusive};
|
||||
|
@ -22,7 +23,6 @@ use erg_common::fresh::fresh_varname;
|
|||
use erg_common::log;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{LimitedDisplay, StructuralEq};
|
||||
use erg_common::vis::Field;
|
||||
use erg_common::{enum_unwrap, fmt_option, ref_addr_eq, set, Str};
|
||||
|
||||
use erg_parser::token::TokenKind;
|
||||
|
@ -35,6 +35,7 @@ use typaram::{IntervalOp, TyParam};
|
|||
use value::value_set::*;
|
||||
use value::ValueObj;
|
||||
use value::ValueObj::{Inf, NegInf};
|
||||
pub use vis::*;
|
||||
|
||||
/// cloneのコストがあるためなるべく.ref_tを使うようにすること
|
||||
/// いくつかの構造体は直接Typeを保持していないので、その場合は.tを使う
|
||||
|
@ -534,9 +535,6 @@ impl LimitedDisplay for RefinementType {
|
|||
write!(f, "{rhs}, ")?;
|
||||
}
|
||||
write!(f, "}}")?;
|
||||
if cfg!(feature = "debug") {
|
||||
write!(f, "(<: {})", self.t)?;
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
write!(f, "{{{}: ", self.var)?;
|
||||
|
|
|
@ -7,7 +7,6 @@ use erg_common::dict::Dict;
|
|||
use erg_common::set;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{LimitedDisplay, StructuralEq};
|
||||
use erg_common::vis::Field;
|
||||
use erg_common::Str;
|
||||
use erg_common::{dict, log};
|
||||
|
||||
|
@ -19,7 +18,7 @@ use super::free::{
|
|||
};
|
||||
use super::value::ValueObj;
|
||||
use super::Type;
|
||||
use super::{ConstSubr, ParamTy, UserConstSubr};
|
||||
use super::{ConstSubr, Field, ParamTy, UserConstSubr};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(u8)]
|
||||
|
|
|
@ -16,7 +16,6 @@ use erg_common::python_util::PythonVersion;
|
|||
use erg_common::serialize::*;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::shared::Shared;
|
||||
use erg_common::vis::Field;
|
||||
use erg_common::{dict, fmt_iter, impl_display_from_debug, log, switch_lang};
|
||||
use erg_common::{RcArray, Str};
|
||||
use erg_parser::ast::{ConstArgs, ConstExpr};
|
||||
|
@ -28,7 +27,7 @@ use self::value_set::inner_class;
|
|||
use super::codeobj::CodeObj;
|
||||
use super::constructors::{array_t, dict_t, mono, poly, refinement, set_t, tuple_t};
|
||||
use super::typaram::TyParam;
|
||||
use super::{ConstSubr, HasType, Predicate, Type};
|
||||
use super::{ConstSubr, Field, HasType, Predicate, Type};
|
||||
|
||||
pub struct EvalValueError(pub Box<ErrorCore>);
|
||||
|
||||
|
@ -1311,11 +1310,11 @@ impl ValueObj {
|
|||
}
|
||||
Self::Subr(subr) => subr.as_type().map(TypeObj::Builtin),
|
||||
Self::Array(elems) | Self::Tuple(elems) => {
|
||||
erg_common::log!(err "as_type({})", erg_common::fmt_vec(elems));
|
||||
log!(err "as_type({})", erg_common::fmt_vec(elems));
|
||||
None
|
||||
}
|
||||
Self::Dict(elems) => {
|
||||
erg_common::log!(err "as_type({elems})");
|
||||
log!(err "as_type({elems})");
|
||||
None
|
||||
}
|
||||
_other => None,
|
||||
|
|
233
crates/erg_compiler/ty/vis.rs
Normal file
233
crates/erg_compiler/ty/vis.rs
Normal file
|
@ -0,0 +1,233 @@
|
|||
use std::borrow::Borrow;
|
||||
use std::fmt;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::{switch_lang, Str};
|
||||
|
||||
use erg_parser::ast::AccessModifier;
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::ty::Type;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum VisibilityModifier {
|
||||
Public,
|
||||
Private,
|
||||
Restricted(Set<Str>),
|
||||
SubtypeRestricted(Type),
|
||||
}
|
||||
|
||||
impl fmt::Display for VisibilityModifier {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Private => write!(f, "::"),
|
||||
Self::Public => write!(f, "."),
|
||||
Self::Restricted(namespaces) => write!(f, "::[{namespaces}]"),
|
||||
Self::SubtypeRestricted(typ) => write!(f, "::[<: {typ}]"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VisibilityModifier {
|
||||
pub const fn is_public(&self) -> bool {
|
||||
matches!(self, Self::Public)
|
||||
}
|
||||
pub const fn is_private(&self) -> bool {
|
||||
matches!(self, Self::Private)
|
||||
}
|
||||
|
||||
pub const fn display_as_accessor(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Public => ".",
|
||||
Self::Private | Self::Restricted(_) | Self::SubtypeRestricted(_) => "::",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display(&self) -> String {
|
||||
match self {
|
||||
Self::Private => switch_lang!(
|
||||
"japanese" => "非公開",
|
||||
"simplified_chinese" => "私有",
|
||||
"traditional_chinese" => "私有",
|
||||
"english" => "private",
|
||||
)
|
||||
.into(),
|
||||
Self::Public => switch_lang!(
|
||||
"japanese" => "公開",
|
||||
"simplified_chinese" => "公开",
|
||||
"traditional_chinese" => "公開",
|
||||
"english" => "public",
|
||||
)
|
||||
.into(),
|
||||
Self::Restricted(namespaces) => switch_lang!(
|
||||
"japanese" => format!("制限付き公開({namespaces}でのみ公開)"),
|
||||
"simplified_chinese" => format!("受限公开({namespaces}中可见)"),
|
||||
"traditional_chinese" => format!("受限公開({namespaces}中可見)"),
|
||||
"english" => format!("restricted public ({namespaces} only)"),
|
||||
),
|
||||
Self::SubtypeRestricted(typ) => switch_lang!(
|
||||
"japanese" => format!("制限付き公開({typ}の部分型でのみ公開)"),
|
||||
"simplified_chinese" => format!("受限公开({typ}的子类型中可见)"),
|
||||
"traditional_chinese" => format!("受限公開({typ}的子類型中可見)"),
|
||||
"english" => format!("restricted public (subtypes of {typ} only)"),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Visibility {
|
||||
pub modifier: VisibilityModifier,
|
||||
pub def_namespace: Str,
|
||||
}
|
||||
|
||||
impl Visibility {
|
||||
pub const DUMMY_PRIVATE: Self = Self {
|
||||
modifier: VisibilityModifier::Private,
|
||||
def_namespace: Str::ever("<dummy>"),
|
||||
};
|
||||
pub const DUMMY_PUBLIC: Self = Self {
|
||||
modifier: VisibilityModifier::Public,
|
||||
def_namespace: Str::ever("<dummy>"),
|
||||
};
|
||||
pub const BUILTIN_PRIVATE: Self = Self {
|
||||
modifier: VisibilityModifier::Private,
|
||||
def_namespace: Str::ever("<builtins>"),
|
||||
};
|
||||
pub const BUILTIN_PUBLIC: Self = Self {
|
||||
modifier: VisibilityModifier::Public,
|
||||
def_namespace: Str::ever("<builtins>"),
|
||||
};
|
||||
|
||||
pub const fn new(modifier: VisibilityModifier, def_namespace: Str) -> Self {
|
||||
Self {
|
||||
modifier,
|
||||
def_namespace,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn private<S: Into<Str>>(namespace: S) -> Self {
|
||||
Self {
|
||||
modifier: VisibilityModifier::Private,
|
||||
def_namespace: namespace.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn is_public(&self) -> bool {
|
||||
self.modifier.is_public()
|
||||
}
|
||||
pub const fn is_private(&self) -> bool {
|
||||
self.modifier.is_private()
|
||||
}
|
||||
|
||||
pub fn compatible(&self, access: &AccessModifier, namespace: &Context) -> bool {
|
||||
match (&self.modifier, access) {
|
||||
(_, AccessModifier::Force) => true,
|
||||
(VisibilityModifier::Public, AccessModifier::Auto | AccessModifier::Public) => true,
|
||||
// compatible example:
|
||||
// def_namespace: <module>::C
|
||||
// namespace: <module>::C::f
|
||||
(VisibilityModifier::Private, AccessModifier::Auto | AccessModifier::Private) => {
|
||||
&self.def_namespace[..] == "<builtins>"
|
||||
|| namespace.name.starts_with(&self.def_namespace[..])
|
||||
}
|
||||
(
|
||||
VisibilityModifier::Restricted(namespaces),
|
||||
AccessModifier::Auto | AccessModifier::Private,
|
||||
) => {
|
||||
namespace.name.starts_with(&self.def_namespace[..])
|
||||
|| namespaces.contains(&namespace.name)
|
||||
}
|
||||
(
|
||||
VisibilityModifier::SubtypeRestricted(typ),
|
||||
AccessModifier::Auto | AccessModifier::Private,
|
||||
) => {
|
||||
namespace.name.starts_with(&self.def_namespace[..]) || {
|
||||
let Some(space_t) = namespace.rec_get_self_t() else {
|
||||
return false;
|
||||
};
|
||||
namespace.subtype_of(&space_t, typ)
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// same structure as `Identifier`, but only for Record fields.
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
pub struct Field {
|
||||
pub vis: VisibilityModifier,
|
||||
pub symbol: Str,
|
||||
}
|
||||
|
||||
impl PartialEq for Field {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.symbol == other.symbol
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for Field {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.symbol.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Field {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}{}", self.vis, self.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<str> for Field {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &str {
|
||||
&self.symbol[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<Str> for Field {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &Str {
|
||||
&self.symbol
|
||||
}
|
||||
}
|
||||
|
||||
impl Field {
|
||||
pub const fn new(vis: VisibilityModifier, symbol: Str) -> Self {
|
||||
Field { vis, symbol }
|
||||
}
|
||||
|
||||
pub fn private(symbol: Str) -> Self {
|
||||
Field::new(VisibilityModifier::Private, symbol)
|
||||
}
|
||||
|
||||
pub fn public(symbol: Str) -> Self {
|
||||
Field::new(VisibilityModifier::Public, symbol)
|
||||
}
|
||||
|
||||
pub fn is_const(&self) -> bool {
|
||||
self.symbol.starts_with(char::is_uppercase)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use erg_common::dict;
|
||||
|
||||
#[test]
|
||||
fn test_std_key() {
|
||||
let dict = dict! {Str::ever("a") => 1, Str::rc("b") => 2};
|
||||
assert_eq!(dict.get("a"), Some(&1));
|
||||
assert_eq!(dict.get("b"), Some(&2));
|
||||
assert_eq!(dict.get(&Str::ever("b")), Some(&2));
|
||||
assert_eq!(dict.get(&Str::rc("b")), Some(&2));
|
||||
|
||||
let dict = dict! {Field::private(Str::ever("a")) => 1, Field::public(Str::ever("b")) => 2};
|
||||
assert_eq!(dict.get("a"), Some(&1));
|
||||
assert_eq!(dict.get("b"), Some(&2));
|
||||
}
|
||||
}
|
|
@ -3,14 +3,12 @@ use std::path::PathBuf;
|
|||
|
||||
use erg_common::error::Location;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::vis::{Field, Visibility};
|
||||
use erg_common::Str;
|
||||
use Visibility::*;
|
||||
|
||||
use erg_parser::ast::DefId;
|
||||
|
||||
use crate::context::DefaultInfo;
|
||||
use crate::ty::{HasType, Type};
|
||||
use crate::ty::{Field, HasType, Type, Visibility};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(u8)]
|
||||
|
@ -200,18 +198,31 @@ impl HasType for VarInfo {
|
|||
|
||||
impl Default for VarInfo {
|
||||
fn default() -> Self {
|
||||
Self::const_default()
|
||||
Self::const_default_private()
|
||||
}
|
||||
}
|
||||
|
||||
impl VarInfo {
|
||||
pub const ILLEGAL: &'static Self = &Self::const_default();
|
||||
pub const ILLEGAL: &'static Self = &Self::const_default_private();
|
||||
|
||||
pub const fn const_default() -> Self {
|
||||
pub const fn const_default_private() -> Self {
|
||||
Self::new(
|
||||
Type::Failure,
|
||||
Immutable,
|
||||
Private,
|
||||
Visibility::DUMMY_PRIVATE,
|
||||
VarKind::DoesNotExist,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
AbsLocation::unknown(),
|
||||
)
|
||||
}
|
||||
|
||||
pub const fn const_default_public() -> Self {
|
||||
Self::new(
|
||||
Type::Failure,
|
||||
Immutable,
|
||||
Visibility::DUMMY_PUBLIC,
|
||||
VarKind::DoesNotExist,
|
||||
None,
|
||||
None,
|
||||
|
@ -250,16 +261,25 @@ impl VarInfo {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn nd_parameter(t: Type, def_loc: AbsLocation) -> Self {
|
||||
pub fn nd_parameter(t: Type, def_loc: AbsLocation, namespace: Str) -> Self {
|
||||
let kind = VarKind::Parameter {
|
||||
def_id: DefId(0),
|
||||
var: false,
|
||||
default: DefaultInfo::NonDefault,
|
||||
};
|
||||
Self::new(t, Immutable, Private, kind, None, None, None, def_loc)
|
||||
Self::new(
|
||||
t,
|
||||
Immutable,
|
||||
Visibility::private(namespace),
|
||||
kind,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
def_loc,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn instance_attr(field: Field, t: Type, impl_of: Option<Type>) -> Self {
|
||||
pub fn instance_attr(field: Field, t: Type, impl_of: Option<Type>, namespace: Str) -> Self {
|
||||
let muty = if field.is_const() {
|
||||
Mutability::Const
|
||||
} else {
|
||||
|
@ -269,7 +289,7 @@ impl VarInfo {
|
|||
Self::new(
|
||||
t,
|
||||
muty,
|
||||
field.vis,
|
||||
Visibility::new(field.vis, namespace),
|
||||
kind,
|
||||
None,
|
||||
impl_of,
|
||||
|
|
|
@ -7,7 +7,6 @@ use erg_common::error::Location;
|
|||
use erg_common::set::Set as HashSet;
|
||||
// use erg_common::dict::Dict as HashMap;
|
||||
use erg_common::traits::{Locational, NestedDisplay, Stream};
|
||||
use erg_common::vis::{Field, Visibility};
|
||||
use erg_common::{
|
||||
fmt_option, fmt_vec, impl_display_for_enum, impl_display_for_single_struct,
|
||||
impl_display_from_nested, impl_displayable_stream_for_wrapper, impl_from_trait_for_enum,
|
||||
|
@ -493,11 +492,31 @@ impl_locational_for_enum!(Accessor; Ident, Attr, TupleAttr, Subscr, TypeApp);
|
|||
|
||||
impl Accessor {
|
||||
pub const fn local(symbol: Token) -> Self {
|
||||
Self::Ident(Identifier::new(None, VarName::new(symbol)))
|
||||
Self::Ident(Identifier::new(
|
||||
VisModifierSpec::Private,
|
||||
VarName::new(symbol),
|
||||
))
|
||||
}
|
||||
|
||||
pub const fn public(dot: Token, symbol: Token) -> Self {
|
||||
Self::Ident(Identifier::new(Some(dot), VarName::new(symbol)))
|
||||
Self::Ident(Identifier::new(
|
||||
VisModifierSpec::Public(dot),
|
||||
VarName::new(symbol),
|
||||
))
|
||||
}
|
||||
|
||||
pub const fn explicit_local(dcolon: Token, symbol: Token) -> Self {
|
||||
Self::Ident(Identifier::new(
|
||||
VisModifierSpec::ExplicitPrivate(dcolon),
|
||||
VarName::new(symbol),
|
||||
))
|
||||
}
|
||||
|
||||
pub const fn restricted(rest: VisRestriction, symbol: Token) -> Self {
|
||||
Self::Ident(Identifier::new(
|
||||
VisModifierSpec::Restricted(rest),
|
||||
VarName::new(symbol),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn attr(obj: Expr, ident: Identifier) -> Self {
|
||||
|
@ -1201,7 +1220,7 @@ impl Call {
|
|||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct DataPack {
|
||||
pub class: Box<Expr>,
|
||||
pub connector: Token,
|
||||
pub connector: VisModifierSpec,
|
||||
pub args: Record,
|
||||
}
|
||||
|
||||
|
@ -1220,7 +1239,7 @@ impl Locational for DataPack {
|
|||
}
|
||||
|
||||
impl DataPack {
|
||||
pub fn new(class: Expr, connector: Token, args: Record) -> Self {
|
||||
pub fn new(class: Expr, connector: VisModifierSpec, args: Record) -> Self {
|
||||
Self {
|
||||
class: Box::new(class),
|
||||
connector,
|
||||
|
@ -1392,7 +1411,10 @@ impl_locational_for_enum!(ConstAccessor; Local, SelfDot, Attr, TupleAttr, Subscr
|
|||
|
||||
impl ConstAccessor {
|
||||
pub const fn local(symbol: Token) -> Self {
|
||||
Self::Local(ConstIdentifier::new(None, VarName::new(symbol)))
|
||||
Self::Local(ConstIdentifier::new(
|
||||
VisModifierSpec::Private,
|
||||
VarName::new(symbol),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn attr(obj: ConstExpr, name: ConstIdentifier) -> Self {
|
||||
|
@ -2655,18 +2677,108 @@ impl VarName {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Namespaces(Vec<Accessor>);
|
||||
|
||||
impl_displayable_stream_for_wrapper!(Namespaces, Accessor);
|
||||
|
||||
impl NestedDisplay for Namespaces {
|
||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||
for (i, ns) in self.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{ns}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Locational for Namespaces {
|
||||
fn loc(&self) -> Location {
|
||||
Location::concat(self.first().unwrap(), self.last().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum VisRestriction {
|
||||
Namespaces(Namespaces),
|
||||
SubtypeOf(Box<TypeSpec>),
|
||||
}
|
||||
|
||||
impl_locational_for_enum!(VisRestriction; Namespaces, SubtypeOf);
|
||||
impl_display_from_nested!(VisRestriction);
|
||||
|
||||
impl NestedDisplay for VisRestriction {
|
||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||
match self {
|
||||
Self::Namespaces(ns) => write!(f, "{ns}"),
|
||||
Self::SubtypeOf(ty) => write!(f, "<: {ty}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum VisModifierSpec {
|
||||
Private,
|
||||
Auto,
|
||||
Public(Token),
|
||||
ExplicitPrivate(Token),
|
||||
Restricted(VisRestriction),
|
||||
}
|
||||
|
||||
impl NestedDisplay for VisModifierSpec {
|
||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||
match self {
|
||||
Self::Private => Ok(()),
|
||||
Self::Auto => write!(f, ":auto:"),
|
||||
Self::Public(_token) => write!(f, "."),
|
||||
Self::ExplicitPrivate(_token) => write!(f, "::"),
|
||||
Self::Restricted(rest) => write!(f, "::[{rest}]"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_display_from_nested!(VisModifierSpec);
|
||||
|
||||
impl Locational for VisModifierSpec {
|
||||
fn loc(&self) -> Location {
|
||||
match self {
|
||||
Self::Private | Self::Auto => Location::Unknown,
|
||||
Self::Public(token) => token.loc(),
|
||||
Self::ExplicitPrivate(token) => token.loc(),
|
||||
Self::Restricted(rest) => rest.loc(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VisModifierSpec {
|
||||
pub const fn is_public(&self) -> bool {
|
||||
matches!(self, Self::Public(_))
|
||||
}
|
||||
|
||||
pub const fn is_private(&self) -> bool {
|
||||
matches!(self, Self::Private | Self::ExplicitPrivate(_))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum AccessModifier {
|
||||
Private, // `::`
|
||||
Public, // `.`
|
||||
Auto, // record unpacking
|
||||
Force, // can access any identifiers
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Identifier {
|
||||
pub dot: Option<Token>,
|
||||
pub vis: VisModifierSpec,
|
||||
pub name: VarName,
|
||||
}
|
||||
|
||||
impl NestedDisplay for Identifier {
|
||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||
match &self.dot {
|
||||
Some(_dot) => write!(f, ".{}", self.name),
|
||||
None => write!(f, "::{}", self.name),
|
||||
}
|
||||
write!(f, "{}{}", self.vis, self.name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2674,24 +2786,16 @@ impl_display_from_nested!(Identifier);
|
|||
|
||||
impl Locational for Identifier {
|
||||
fn loc(&self) -> Location {
|
||||
if let Some(dot) = &self.dot {
|
||||
if dot.loc().is_unknown() {
|
||||
self.name.loc()
|
||||
} else {
|
||||
Location::concat(dot, &self.name)
|
||||
match &self.vis {
|
||||
VisModifierSpec::Private | VisModifierSpec::Auto => self.name.loc(),
|
||||
VisModifierSpec::ExplicitPrivate(token) | VisModifierSpec::Public(token) => {
|
||||
Location::concat(token, &self.name)
|
||||
}
|
||||
} else {
|
||||
self.name.loc()
|
||||
VisModifierSpec::Restricted(args) => Location::concat(args, &self.name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Identifier> for Field {
|
||||
fn from(ident: &Identifier) -> Self {
|
||||
Self::new(ident.vis(), ident.inspect().clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Identifier> for Expr {
|
||||
fn from(ident: Identifier) -> Self {
|
||||
Self::Accessor(Accessor::Ident(ident))
|
||||
|
@ -2699,34 +2803,52 @@ impl From<Identifier> for Expr {
|
|||
}
|
||||
|
||||
impl Identifier {
|
||||
pub const fn new(dot: Option<Token>, name: VarName) -> Self {
|
||||
Self { dot, name }
|
||||
pub const fn new(vis: VisModifierSpec, name: VarName) -> Self {
|
||||
Self { vis, name }
|
||||
}
|
||||
|
||||
pub fn static_public(name: &'static str) -> Self {
|
||||
Self::new(
|
||||
Some(Token::from_str(TokenKind::Dot, ".")),
|
||||
VisModifierSpec::Public(Token::from_str(TokenKind::Dot, ".")),
|
||||
VarName::from_static(name),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn public(name: Str) -> Self {
|
||||
Self::new(
|
||||
Some(Token::from_str(TokenKind::Dot, ".")),
|
||||
VisModifierSpec::Public(Token::from_str(TokenKind::Dot, ".")),
|
||||
VarName::from_str(name),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn private(name: Str) -> Self {
|
||||
Self::new(None, VarName::from_str(name))
|
||||
Self::new(VisModifierSpec::Private, VarName::from_str(name))
|
||||
}
|
||||
|
||||
pub fn private_from_token(symbol: Token) -> Self {
|
||||
Self::new(VisModifierSpec::Private, VarName::new(symbol))
|
||||
}
|
||||
|
||||
pub fn private_from_varname(name: VarName) -> Self {
|
||||
Self::new(VisModifierSpec::Private, name)
|
||||
}
|
||||
|
||||
pub fn private_with_line(name: Str, line: u32) -> Self {
|
||||
Self::new(None, VarName::from_str_and_line(name, line))
|
||||
Self::new(
|
||||
VisModifierSpec::Private,
|
||||
VarName::from_str_and_line(name, line),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn public_with_line(dot: Token, name: Str, line: u32) -> Self {
|
||||
Self::new(Some(dot), VarName::from_str_and_line(name, line))
|
||||
Self::new(
|
||||
VisModifierSpec::Public(dot),
|
||||
VarName::from_str_and_line(name, line),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn public_from_token(dot: Token, symbol: Token) -> Self {
|
||||
Self::new(VisModifierSpec::Public(dot), VarName::new(symbol))
|
||||
}
|
||||
|
||||
pub fn is_const(&self) -> bool {
|
||||
|
@ -2737,10 +2859,13 @@ impl Identifier {
|
|||
self.name.is_raw()
|
||||
}
|
||||
|
||||
pub const fn vis(&self) -> Visibility {
|
||||
match &self.dot {
|
||||
Some(_) => Visibility::Public,
|
||||
None => Visibility::Private,
|
||||
pub fn acc_kind(&self) -> AccessModifier {
|
||||
match &self.vis {
|
||||
VisModifierSpec::Auto => AccessModifier::Auto,
|
||||
VisModifierSpec::Public(_) => AccessModifier::Public,
|
||||
VisModifierSpec::ExplicitPrivate(_)
|
||||
| VisModifierSpec::Restricted(_)
|
||||
| VisModifierSpec::Private => AccessModifier::Private,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2983,11 +3108,11 @@ impl VarPattern {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn vis(&self) -> Visibility {
|
||||
pub fn vis(&self) -> &VisModifierSpec {
|
||||
match self {
|
||||
Self::Ident(ident) => ident.vis(),
|
||||
Self::Ident(ident) => &ident.vis,
|
||||
// TODO: `[.x, .y]`?
|
||||
_ => Visibility::Private,
|
||||
_ => &VisModifierSpec::Private,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3036,7 +3161,7 @@ impl VarSignature {
|
|||
self.pat.is_const()
|
||||
}
|
||||
|
||||
pub const fn vis(&self) -> Visibility {
|
||||
pub fn vis(&self) -> &VisModifierSpec {
|
||||
self.pat.vis()
|
||||
}
|
||||
|
||||
|
@ -3493,8 +3618,8 @@ impl SubrSignature {
|
|||
self.ident.is_const()
|
||||
}
|
||||
|
||||
pub const fn vis(&self) -> Visibility {
|
||||
self.ident.vis()
|
||||
pub fn vis(&self) -> &VisModifierSpec {
|
||||
&self.ident.vis
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3693,7 +3818,7 @@ impl Signature {
|
|||
matches!(self, Self::Subr(_))
|
||||
}
|
||||
|
||||
pub const fn vis(&self) -> Visibility {
|
||||
pub fn vis(&self) -> &VisModifierSpec {
|
||||
match self {
|
||||
Self::Var(var) => var.vis(),
|
||||
Self::Subr(subr) => subr.vis(),
|
||||
|
@ -3893,13 +4018,13 @@ impl ReDef {
|
|||
pub struct Methods {
|
||||
pub class: TypeSpec,
|
||||
pub class_as_expr: Box<Expr>,
|
||||
pub vis: Token, // `.` or `::`
|
||||
pub vis: VisModifierSpec, // `.` or `::`
|
||||
pub attrs: ClassAttrs,
|
||||
}
|
||||
|
||||
impl NestedDisplay for Methods {
|
||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
||||
writeln!(f, "{}{}", self.class, self.vis.content)?;
|
||||
writeln!(f, "{}{}", self.class, self.vis)?;
|
||||
self.attrs.fmt_nest(f, level + 1)
|
||||
}
|
||||
}
|
||||
|
@ -3908,7 +4033,12 @@ impl_display_from_nested!(Methods);
|
|||
impl_locational!(Methods, class, attrs);
|
||||
|
||||
impl Methods {
|
||||
pub fn new(class: TypeSpec, class_as_expr: Expr, vis: Token, attrs: ClassAttrs) -> Self {
|
||||
pub fn new(
|
||||
class: TypeSpec,
|
||||
class_as_expr: Expr,
|
||||
vis: VisModifierSpec,
|
||||
attrs: ClassAttrs,
|
||||
) -> Self {
|
||||
Self {
|
||||
class,
|
||||
class_as_expr: Box::new(class_as_expr),
|
||||
|
@ -3916,14 +4046,6 @@ impl Methods {
|
|||
attrs,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vis(&self) -> Visibility {
|
||||
if self.vis.is(TokenKind::Dot) {
|
||||
Visibility::Public
|
||||
} else {
|
||||
Visibility::Private
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::ast::{
|
|||
ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, ReDef, Record, RecordAttrOrIdent,
|
||||
RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple, TupleTypeSpec,
|
||||
TypeAppArgs, TypeAppArgsKind, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName,
|
||||
VarPattern, VarRecordAttr, VarSignature,
|
||||
VarPattern, VarRecordAttr, VarSignature, VisModifierSpec,
|
||||
};
|
||||
use crate::token::{Token, TokenKind, COLON, DOT};
|
||||
|
||||
|
@ -636,7 +636,10 @@ impl Desugarer {
|
|||
r_brace,
|
||||
)
|
||||
}
|
||||
BufIndex::Record(attr) => obj.attr(attr.clone()),
|
||||
BufIndex::Record(attr) => {
|
||||
let attr = Identifier::new(VisModifierSpec::Auto, attr.name.clone());
|
||||
obj.attr(attr)
|
||||
}
|
||||
};
|
||||
let id = DefId(get_hash(&(&acc, buf_name)));
|
||||
let block = Block::new(vec![Expr::Accessor(acc)]);
|
||||
|
@ -1001,7 +1004,10 @@ impl Desugarer {
|
|||
r_brace,
|
||||
)
|
||||
}
|
||||
BufIndex::Record(attr) => obj.attr(attr.clone()),
|
||||
BufIndex::Record(attr) => {
|
||||
let attr = Identifier::new(VisModifierSpec::Auto, attr.name.clone());
|
||||
obj.attr(attr)
|
||||
}
|
||||
};
|
||||
let id = DefId(get_hash(&(&acc, buf_name)));
|
||||
let block = Block::new(vec![Expr::Accessor(acc)]);
|
||||
|
@ -1166,7 +1172,7 @@ impl Desugarer {
|
|||
}
|
||||
*/
|
||||
ParamPattern::VarName(name) => {
|
||||
let ident = Identifier::new(None, name.clone());
|
||||
let ident = Identifier::new(VisModifierSpec::Private, name.clone());
|
||||
let v = VarSignature::new(
|
||||
VarPattern::Ident(ident),
|
||||
sig.t_spec.as_ref().map(|ts| ts.t_spec.clone()),
|
||||
|
|
|
@ -560,6 +560,37 @@ impl Parser {
|
|||
Ok(TypeAppArgs::new(l_vbar, args, r_vbar))
|
||||
}
|
||||
|
||||
fn try_reduce_restriction(&mut self) -> ParseResult<VisRestriction> {
|
||||
debug_call_info!(self);
|
||||
expect_pop!(self, LSqBr);
|
||||
let rest = match self.peek_kind() {
|
||||
Some(SubtypeOf) => {
|
||||
self.lpop();
|
||||
let t_spec_as_expr = self
|
||||
.try_reduce_expr(false, true, false, false)
|
||||
.map_err(|_| self.stack_dec(fn_name!()))?;
|
||||
match Parser::expr_to_type_spec(t_spec_as_expr) {
|
||||
Ok(t_spec) => VisRestriction::SubtypeOf(Box::new(t_spec)),
|
||||
Err(err) => {
|
||||
self.errs.push(err);
|
||||
debug_exit_info!(self);
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// FIXME: reduce namespaces
|
||||
let acc = self
|
||||
.try_reduce_acc_lhs()
|
||||
.map_err(|_| self.stack_dec(fn_name!()))?;
|
||||
VisRestriction::Namespaces(Namespaces::new(vec![acc]))
|
||||
}
|
||||
};
|
||||
expect_pop!(self, RSqBr);
|
||||
debug_exit_info!(self);
|
||||
Ok(rest)
|
||||
}
|
||||
|
||||
fn try_reduce_acc_lhs(&mut self) -> ParseResult<Accessor> {
|
||||
debug_call_info!(self);
|
||||
let acc = match self.peek_kind() {
|
||||
|
@ -576,6 +607,19 @@ impl Parser {
|
|||
return Err(());
|
||||
}
|
||||
}
|
||||
Some(DblColon) => {
|
||||
let dbl_colon = self.lpop();
|
||||
if let Some(LSqBr) = self.peek_kind() {
|
||||
let rest = self
|
||||
.try_reduce_restriction()
|
||||
.map_err(|_| self.stack_dec(fn_name!()))?;
|
||||
let symbol = expect_pop!(self, Symbol);
|
||||
Accessor::restricted(rest, symbol)
|
||||
} else {
|
||||
let symbol = expect_pop!(self, Symbol);
|
||||
Accessor::explicit_local(dbl_colon, symbol)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let err = self.skip_and_throw_syntax_err(caused_by!());
|
||||
self.errs.push(err);
|
||||
|
@ -1000,7 +1044,11 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
fn try_reduce_method_defs(&mut self, class: Expr, vis: Token) -> ParseResult<Methods> {
|
||||
fn try_reduce_method_defs(
|
||||
&mut self,
|
||||
class: Expr,
|
||||
vis: VisModifierSpec,
|
||||
) -> ParseResult<Methods> {
|
||||
debug_call_info!(self);
|
||||
expect_pop!(self, fail_next Indent);
|
||||
while self.cur_is(Newline) {
|
||||
|
@ -1205,7 +1253,7 @@ impl Parser {
|
|||
));
|
||||
}
|
||||
Some(t) if t.is(DblColon) => {
|
||||
let vis = self.lpop();
|
||||
let vis = VisModifierSpec::ExplicitPrivate(self.lpop());
|
||||
match self.lpop() {
|
||||
symbol if symbol.is(Symbol) => {
|
||||
let Some(ExprOrOp::Expr(obj)) = stack.pop() else {
|
||||
|
@ -1219,11 +1267,13 @@ impl Parser {
|
|||
.transpose()
|
||||
.map_err(|_| self.stack_dec(fn_name!()))?
|
||||
{
|
||||
let ident = Identifier::new(None, VarName::new(symbol));
|
||||
let ident =
|
||||
Identifier::new(VisModifierSpec::Private, VarName::new(symbol));
|
||||
let call = Call::new(obj, Some(ident), args);
|
||||
stack.push(ExprOrOp::Expr(Expr::Call(call)));
|
||||
} else {
|
||||
let ident = Identifier::new(None, VarName::new(symbol));
|
||||
let ident =
|
||||
Identifier::new(VisModifierSpec::Private, VarName::new(symbol));
|
||||
stack.push(ExprOrOp::Expr(obj.attr_expr(ident)));
|
||||
}
|
||||
}
|
||||
|
@ -1267,7 +1317,7 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
Some(t) if t.is(Dot) => {
|
||||
let vis = self.lpop();
|
||||
let dot = self.lpop();
|
||||
match self.lpop() {
|
||||
symbol if symbol.is(Symbol) => {
|
||||
let Some(ExprOrOp::Expr(obj)) = stack.pop() else {
|
||||
|
@ -1281,15 +1331,16 @@ impl Parser {
|
|||
.transpose()
|
||||
.map_err(|_| self.stack_dec(fn_name!()))?
|
||||
{
|
||||
let ident = Identifier::new(Some(vis), VarName::new(symbol));
|
||||
let ident = Identifier::public_from_token(dot, symbol);
|
||||
let call = Expr::Call(Call::new(obj, Some(ident), args));
|
||||
stack.push(ExprOrOp::Expr(call));
|
||||
} else {
|
||||
let ident = Identifier::new(Some(vis), VarName::new(symbol));
|
||||
let ident = Identifier::public_from_token(dot, symbol);
|
||||
stack.push(ExprOrOp::Expr(obj.attr_expr(ident)));
|
||||
}
|
||||
}
|
||||
line_break if line_break.is(Newline) => {
|
||||
let vis = VisModifierSpec::Public(dot);
|
||||
let maybe_class = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_)));
|
||||
let defs = self
|
||||
.try_reduce_method_defs(maybe_class, vis)
|
||||
|
@ -1488,11 +1539,17 @@ impl Parser {
|
|||
.transpose()
|
||||
.map_err(|_| self.stack_dec(fn_name!()))?
|
||||
{
|
||||
let ident = Identifier::new(Some(vis), VarName::new(symbol));
|
||||
let ident = Identifier::new(
|
||||
VisModifierSpec::Public(vis),
|
||||
VarName::new(symbol),
|
||||
);
|
||||
let call = Call::new(obj, Some(ident), args);
|
||||
stack.push(ExprOrOp::Expr(Expr::Call(call)));
|
||||
} else {
|
||||
let ident = Identifier::new(Some(vis), VarName::new(symbol));
|
||||
let ident = Identifier::new(
|
||||
VisModifierSpec::Public(vis),
|
||||
VarName::new(symbol),
|
||||
);
|
||||
stack.push(ExprOrOp::Expr(obj.attr_expr(ident)));
|
||||
}
|
||||
}
|
||||
|
@ -1696,7 +1753,7 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
}
|
||||
Some(t) if t.is(Symbol) || t.is(Dot) || t.is(UBar) => {
|
||||
Some(t) if t.is(Symbol) || t.is(Dot) || t.is(DblColon) || t.is(UBar) => {
|
||||
let call_or_acc = self
|
||||
.try_reduce_call_or_acc(in_type_args)
|
||||
.map_err(|_| self.stack_dec(fn_name!()))?;
|
||||
|
@ -1861,7 +1918,8 @@ impl Parser {
|
|||
let token = self.lpop();
|
||||
match token.kind {
|
||||
Symbol => {
|
||||
let ident = Identifier::new(Some(vis), VarName::new(token));
|
||||
let ident =
|
||||
Identifier::new(VisModifierSpec::Public(vis), VarName::new(token));
|
||||
obj = obj.attr_expr(ident);
|
||||
}
|
||||
NatLit => {
|
||||
|
@ -1895,7 +1953,10 @@ impl Parser {
|
|||
let token = self.lpop();
|
||||
match token.kind {
|
||||
Symbol => {
|
||||
let ident = Identifier::new(None, VarName::new(token));
|
||||
let ident = Identifier::new(
|
||||
VisModifierSpec::ExplicitPrivate(vis),
|
||||
VarName::new(token),
|
||||
);
|
||||
obj = obj.attr_expr(ident);
|
||||
}
|
||||
LBrace => {
|
||||
|
@ -1905,6 +1966,7 @@ impl Parser {
|
|||
.map_err(|_| self.stack_dec(fn_name!()))?;
|
||||
match args {
|
||||
BraceContainer::Record(args) => {
|
||||
let vis = VisModifierSpec::ExplicitPrivate(vis);
|
||||
obj = Expr::DataPack(DataPack::new(obj, vis, args));
|
||||
}
|
||||
other => {
|
||||
|
@ -2023,15 +2085,15 @@ impl Parser {
|
|||
}
|
||||
|
||||
// Empty brace literals
|
||||
if let Some(first) = self.peek() {
|
||||
if first.is(RBrace) {
|
||||
match self.peek_kind() {
|
||||
Some(RBrace) => {
|
||||
let r_brace = self.lpop();
|
||||
let arg = Args::empty();
|
||||
let set = NormalSet::new(l_brace, r_brace, arg);
|
||||
debug_exit_info!(self);
|
||||
return Ok(BraceContainer::Set(Set::Normal(set)));
|
||||
}
|
||||
if first.is(Equal) {
|
||||
Some(Equal) => {
|
||||
let _eq = self.lpop();
|
||||
if let Some(t) = self.peek() {
|
||||
if t.is(RBrace) {
|
||||
|
@ -2045,7 +2107,7 @@ impl Parser {
|
|||
debug_exit_info!(self);
|
||||
return Err(());
|
||||
}
|
||||
if first.is(Colon) {
|
||||
Some(Colon) => {
|
||||
let _colon = self.lpop();
|
||||
if let Some(t) = self.peek() {
|
||||
if t.is(RBrace) {
|
||||
|
@ -2060,6 +2122,7 @@ impl Parser {
|
|||
debug_exit_info!(self);
|
||||
return Err(());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let first = self
|
||||
|
@ -2541,7 +2604,8 @@ impl Parser {
|
|||
.transpose()
|
||||
.map_err(|_| self.stack_dec(fn_name!()))?
|
||||
{
|
||||
let ident = Identifier::new(Some(vis), VarName::new(symbol));
|
||||
let ident =
|
||||
Identifier::new(VisModifierSpec::Public(vis), VarName::new(symbol));
|
||||
let mut call = Expr::Call(Call::new(obj, Some(ident), args));
|
||||
while let Some(res) = self.opt_reduce_args(false) {
|
||||
let args = res.map_err(|_| self.stack_dec(fn_name!()))?;
|
||||
|
|
|
@ -229,11 +229,12 @@ impl Parser {
|
|||
(ParamPattern::VarName(name), Some(t_spec_with_op)) => {
|
||||
ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec)
|
||||
}
|
||||
(ParamPattern::VarName(name), None) => {
|
||||
ParamTySpec::anonymous(TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple(
|
||||
SimpleTypeSpec::new(Identifier::new(None, name), ConstArgs::empty()),
|
||||
)))
|
||||
}
|
||||
(ParamPattern::VarName(name), None) => ParamTySpec::anonymous(TypeSpec::PreDeclTy(
|
||||
PreDeclTypeSpec::Simple(SimpleTypeSpec::new(
|
||||
Identifier::new(VisModifierSpec::Private, name),
|
||||
ConstArgs::empty(),
|
||||
)),
|
||||
)),
|
||||
_ => todo!(),
|
||||
};
|
||||
non_defaults.push(param);
|
||||
|
@ -247,11 +248,12 @@ impl Parser {
|
|||
(ParamPattern::VarName(name), Some(t_spec_with_op)) => {
|
||||
ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec)
|
||||
}
|
||||
(ParamPattern::VarName(name), None) => {
|
||||
ParamTySpec::anonymous(TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple(
|
||||
SimpleTypeSpec::new(Identifier::new(None, name), ConstArgs::empty()),
|
||||
)))
|
||||
}
|
||||
(ParamPattern::VarName(name), None) => ParamTySpec::anonymous(
|
||||
TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple(SimpleTypeSpec::new(
|
||||
Identifier::new(VisModifierSpec::Private, name),
|
||||
ConstArgs::empty(),
|
||||
))),
|
||||
),
|
||||
_ => todo!(),
|
||||
});
|
||||
let mut defaults = vec![];
|
||||
|
|
|
@ -4,7 +4,7 @@ print! empty
|
|||
|
||||
# Inheritance is prohibited by default. Remove this decorator and check for errors.
|
||||
@Inheritable
|
||||
Point2D = Class {x = Int; y = Int}
|
||||
Point2D = Class {::[<: Self]x = Int; ::[<: Self]y = Int}
|
||||
Point2D::
|
||||
one = 1
|
||||
Point2D.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
UnpackPoint2D = Class {x = Int; y = Int}, Impl := Unpack
|
||||
UnpackPoint2D = Class {.x = Int; .y = Int}, Impl := Unpack
|
||||
|
||||
q = UnpackPoint2D::{x = 1; y = 2}
|
||||
q = UnpackPoint2D::{.x = 1; .y = 2}
|
||||
UnpackPoint2D::{x; y} = q
|
||||
print! x, y
|
||||
|
|
25
tests/should_err/visibility.er
Normal file
25
tests/should_err/visibility.er
Normal file
|
@ -0,0 +1,25 @@
|
|||
@Inheritable
|
||||
Point2D = Class {::[<: Self]x = Int; ::[<: Self]y = Int}
|
||||
Point2D.
|
||||
norm self = self::x**2 + self::y**2 #OK
|
||||
|
||||
Point3D = Inherit Point2D, Additional := {z = Int}
|
||||
Point3D.
|
||||
@Override
|
||||
norm self = self::x**2 + self::y**2 + self::z**2 #OK
|
||||
|
||||
C = Class()
|
||||
C.
|
||||
method point: Point2D = point::x # ERR
|
||||
|
||||
p = Point3D.new {x = 1; y = 2; z = 3}
|
||||
p::x # ERR
|
||||
p.x # ERR
|
||||
p::z # ERR
|
||||
|
||||
rec = {
|
||||
::[f] x = 1
|
||||
}
|
||||
|
||||
f x = rec::x + x # OK
|
||||
g x = rec::x + x # ERR
|
|
@ -1,6 +1,6 @@
|
|||
f {x; y}, [_], (_, _) = x + y
|
||||
f {.x; .y}, [_], (_, _) = x + y
|
||||
|
||||
x = f {x = 1; y = 2}, [3], (4, 5)
|
||||
x = f {.x = 1; .y = 2}, [3], (4, 5)
|
||||
assert x == 3
|
||||
|
||||
#[
|
||||
|
|
|
@ -306,6 +306,11 @@ fn exec_var_args_err() -> Result<(), ()> {
|
|||
expect_failure("tests/should_err/var_args.er", 3)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_visibility() -> Result<(), ()> {
|
||||
expect_failure("tests/should_err/visibility.er", 5)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_move() -> Result<(), ()> {
|
||||
expect_failure("tests/should_err/move.er", 1)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue