mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-03 18:29:00 +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
|
@ -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 {
|
||||
let res = match self.module.context.rec_get_var_info(
|
||||
&ident,
|
||||
AccessKind::Name,
|
||||
&self.cfg.input,
|
||||
&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()
|
||||
}
|
||||
};
|
||||
(
|
||||
self.module.context.rec_get_var_info(
|
||||
&ident,
|
||||
AccessKind::Name,
|
||||
&self.cfg.input,
|
||||
&self.module.context.name,
|
||||
)?,
|
||||
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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue