Skip to content

Commit

Permalink
fix(els): rename not working
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Jan 24, 2024
1 parent 2fdf522 commit c514d0d
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 17 deletions.
7 changes: 7 additions & 0 deletions crates/els/hir_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,13 @@ impl<'a> HIRVisitor<'a> {
return Some(param.sig.vi.clone());
}
}
for guard in params.guards.iter() {
if let GuardClause::Bind(bind) = guard {
if let Some(vi) = self.get_def_info(bind, token) {
return Some(vi);
}
}
}
None
}

Expand Down
4 changes: 3 additions & 1 deletion crates/els/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use lsp_types::{
WorkspaceEdit,
};

#[allow(unused_imports)]
use crate::_log;
use crate::server::{ELSResult, RedirectableStdout, Server};
use crate::util::{self, NormalizedUrl};

Expand All @@ -31,7 +33,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
let uri = NormalizedUrl::new(params.text_document_position.text_document.uri);
let pos = params.text_document_position.position;
if let Some(tok) = self.file_cache.get_symbol(&uri, pos) {
// self.send_log(format!("token: {tok}"))?;
// _log!(self, "tok: {tok}");
if let Some(vi) = self
.get_visitor(&uri)
.and_then(|visitor| visitor.get_info(&tok))
Expand Down
1 change: 1 addition & 0 deletions crates/els/tests/b.er
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
.C = Class { .a = Int }
.C.
func self = self
aplus self, x = self.a + x
13 changes: 13 additions & 0 deletions crates/els/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,19 @@ fn test_rename() -> Result<(), Box<dyn std::error::Error>> {
for (_, change) in edit.changes.unwrap() {
assert_eq!(change.len(), 1);
}
client.notify_save(uri_b.clone().raw())?;
client.wait_diagnostics()?;
let edit = client
.request_rename(uri_b.clone().raw(), 4, 14, "b")?
.unwrap();
assert_eq!(edit.changes.as_ref().unwrap().iter().count(), 2);
for (uri, change) in edit.changes.unwrap() {
if uri.as_str().ends_with("b.er") {
assert_eq!(change.len(), 2);
} else {
assert_eq!(change.len(), 1); // c.er
}
}
Ok(())
}

Expand Down
15 changes: 14 additions & 1 deletion crates/erg_compiler/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,21 @@ fn debind(ident: &Identifier) -> Option<Str> {
}
}

fn escape_name(name: &str, vis: &VisibilityModifier, def_line: u32, def_col: u32) -> Str {
fn escape_name(
name: &str,
vis: &VisibilityModifier,
def_line: u32,
def_col: u32,
is_attr: bool,
) -> Str {
let name = name.replace('!', "__erg_proc__");
let name = name.replace('$', "__erg_shared__");
// For public APIs, mangling is not performed because `hasattr`, etc. cannot be used.
// For automatically generated variables, there is no possibility of conflict.
if vis.is_private() && !name.starts_with('%') {
if is_attr {
return Str::from(format!("::{name}"));
}
let line_mangling = match (def_line, def_col) {
(0, 0) => "".to_string(),
(0, _) => format!("_C{def_col}"),
Expand All @@ -115,6 +124,7 @@ fn escape_ident(ident: Identifier) -> Str {
&ident.vi.vis.modifier,
ident.vi.def_loc.loc.ln_begin().unwrap_or(0),
ident.vi.def_loc.loc.col_begin().unwrap_or(0),
ident.vi.kind.is_instance_attr(),
)
} else if let Some(py_name) = ident.vi.py_name {
py_name
Expand All @@ -126,6 +136,7 @@ fn escape_ident(ident: Identifier) -> Str {
vis,
ident.vi.def_loc.loc.ln_begin().unwrap_or(0),
ident.vi.def_loc.loc.col_begin().unwrap_or(0),
ident.vi.kind.is_instance_attr(),
)
}
}
Expand Down Expand Up @@ -1055,6 +1066,7 @@ impl PyCodeGenerator {
&VisibilityModifier::Public,
vi.def_loc.loc.ln_begin().unwrap_or(0),
vi.def_loc.loc.col_begin().unwrap_or(0),
false,
)
.to_string()
}
Expand Down Expand Up @@ -1430,6 +1442,7 @@ impl PyCodeGenerator {
&VisibilityModifier::Public,
0,
0,
false,
)
})
.collect::<Vec<_>>();
Expand Down
12 changes: 11 additions & 1 deletion crates/erg_compiler/context/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -713,8 +713,18 @@ impl Context {
self.pop();
errs
})?;
let call = if let Some(Expr::Call(call)) = &def.body.block.first() {
Some(call)
} else {
None
};
let (_ctx, errs) = self.check_decls_and_pop();
self.register_gen_const(def.sig.ident().unwrap(), obj, def.def_kind().is_other())?;
self.register_gen_const(
def.sig.ident().unwrap(),
obj,
call,
def.def_kind().is_other(),
)?;
if errs.is_empty() {
Ok(ValueObj::None)
} else {
Expand Down
59 changes: 48 additions & 11 deletions crates/erg_compiler/context/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1170,15 +1170,15 @@ impl Context {
let t = Type::Mono(format!("{}{ident}", self.name).into());
let class = GenTypeObj::class(t, None, None, false);
let class = ValueObj::Type(TypeObj::Generated(class));
self.register_gen_const(ident, class, false)
self.register_gen_const(ident, class, Some(call), false)
}
"Trait" => {
let ident = var.ident().unwrap();
let t = Type::Mono(format!("{}{ident}", self.name).into());
let trait_ =
GenTypeObj::trait_(t, TypeObj::builtin_type(Type::Failure), None, false);
let trait_ = ValueObj::Type(TypeObj::Generated(trait_));
self.register_gen_const(ident, trait_, false)
self.register_gen_const(ident, trait_, Some(call), false)
}
_ => Ok(()),
},
Expand All @@ -1189,6 +1189,11 @@ impl Context {
pub(crate) fn register_const_def(&mut self, def: &ast::Def) -> TyCheckResult<()> {
let id = Some(def.body.id);
let __name__ = def.sig.ident().map(|i| i.inspect()).unwrap_or(UBAR);
let call = if let Some(ast::Expr::Call(call)) = &def.body.block.first() {
Some(call)
} else {
None
};
match &def.sig {
ast::Signature::Subr(sig) => {
if sig.is_const() {
Expand Down Expand Up @@ -1226,6 +1231,7 @@ impl Context {
self.register_gen_const(
def.sig.ident().unwrap(),
obj,
call,
def.def_kind().is_other(),
)?;
} else {
Expand Down Expand Up @@ -1266,7 +1272,7 @@ impl Context {
}
self.pop();
if let Some(ident) = sig.ident() {
self.register_gen_const(ident, obj, def.def_kind().is_other())?;
self.register_gen_const(ident, obj, call, def.def_kind().is_other())?;
}
} else {
self.pre_define_var(sig, id)?;
Expand Down Expand Up @@ -1517,6 +1523,7 @@ impl Context {
&mut self,
ident: &Identifier,
obj: ValueObj,
call: Option<&ast::Call>,
alias: bool,
) -> CompileResult<()> {
let vis = self.instantiate_vis_modifier(&ident.vis)?;
Expand All @@ -1538,7 +1545,7 @@ impl Context {
let meta_t = gen.meta_type();
self.register_type_alias(ident, gen.into_typ(), meta_t)
}
TypeObj::Generated(gen) => self.register_gen_type(ident, gen),
TypeObj::Generated(gen) => self.register_gen_type(ident, gen, call),
TypeObj::Builtin { t, meta_t } => self.register_type_alias(ident, t, meta_t),
},
// TODO: not all value objects are comparable
Expand Down Expand Up @@ -1567,6 +1574,7 @@ impl Context {
&mut self,
ident: &Identifier,
gen: GenTypeObj,
call: Option<&ast::Call>,
) -> CompileResult<()> {
match gen {
GenTypeObj::Class(_) => {
Expand All @@ -1579,7 +1587,7 @@ impl Context {
2,
self.level,
);
self.gen_class_new_method(&gen, &mut ctx)?;
self.gen_class_new_method(&gen, call, &mut ctx)?;
self.register_gen_mono_type(ident, gen, ctx, Const)
} else {
let params = gen
Expand All @@ -1599,7 +1607,7 @@ impl Context {
2,
self.level,
);
self.gen_class_new_method(&gen, &mut ctx)?;
self.gen_class_new_method(&gen, call, &mut ctx)?;
self.register_gen_poly_type(ident, gen, ctx, Const)
}
}
Expand Down Expand Up @@ -1641,7 +1649,7 @@ impl Context {
..
} = additional
{
self.register_instance_attrs(&mut ctx, rec)?;
self.register_instance_attrs(&mut ctx, rec, call)?;
}
param_t
.map(|t| self.intersection(t, additional.typ()))
Expand Down Expand Up @@ -1710,7 +1718,7 @@ impl Context {
..
}) = gen.base_or_sup()
{
self.register_instance_attrs(&mut ctx, req)?;
self.register_instance_attrs(&mut ctx, req, call)?;
}
self.register_gen_mono_type(ident, gen, ctx, Const)
} else {
Expand Down Expand Up @@ -1744,7 +1752,7 @@ impl Context {
None
};
if let Some(additional) = additional {
self.register_instance_attrs(&mut ctx, additional)?;
self.register_instance_attrs(&mut ctx, additional, call)?;
}
for sup in super_classes.into_iter() {
if let Some(sup_ctx) = self.get_nominal_type_ctx(&sup) {
Expand Down Expand Up @@ -1802,14 +1810,38 @@ impl Context {
&self,
ctx: &mut Context,
rec: &Dict<Field, Type>,
call: Option<&ast::Call>,
) -> CompileResult<()> {
let record = call.and_then(|call| {
if let Some(ast::Expr::Record(record)) = call
.args
.get_left_or_key("Base")
.or_else(|| call.args.get_left_or_key("Requirement"))
.or_else(|| call.args.get_left_or_key("Super"))
{
Some(record)
} else {
None
}
});
for (field, t) in rec.iter() {
let loc = record
.as_ref()
.and_then(|record| {
record
.keys()
.iter()
.find(|id| id.inspect() == &field.symbol)
.map(|name| self.absolutize(name.loc()))
})
.unwrap_or(AbsLocation::unknown());
let varname = VarName::from_str(field.symbol.clone());
let vi = VarInfo::instance_attr(
field.clone(),
t.clone(),
self.kind.clone(),
ctx.name.clone(),
loc,
);
// self.index().register(&vi);
if let Some(_ent) = ctx.decls.insert(varname.clone(), vi) {
Expand All @@ -1825,15 +1857,20 @@ impl Context {
Ok(())
}

fn gen_class_new_method(&self, gen: &GenTypeObj, ctx: &mut Context) -> CompileResult<()> {
fn gen_class_new_method(
&self,
gen: &GenTypeObj,
call: Option<&ast::Call>,
ctx: &mut Context,
) -> CompileResult<()> {
let mut methods = Self::methods(None, self.cfg.clone(), self.shared.clone(), 2, self.level);
let new_t = if let Some(base) = gen.base_or_sup() {
match base {
TypeObj::Builtin {
t: Type::Record(rec),
..
} => {
self.register_instance_attrs(ctx, rec)?;
self.register_instance_attrs(ctx, rec, call)?;
}
other => {
methods.register_fixed_auto_impl(
Expand Down
4 changes: 3 additions & 1 deletion crates/erg_compiler/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,9 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
Some(py_name),
)?;
if let Some(gen) = ty_obj {
self.module.context.register_gen_type(&new_ident, gen)?;
self.module
.context
.register_gen_type(&new_ident, gen, None)?;
}
Ok(())
}
Expand Down
10 changes: 8 additions & 2 deletions crates/erg_compiler/varinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,13 @@ impl VarInfo {
)
}

pub fn instance_attr(field: Field, t: Type, kind: ContextKind, namespace: Str) -> Self {
pub fn instance_attr(
field: Field,
t: Type,
kind: ContextKind,
namespace: Str,
loc: AbsLocation,
) -> Self {
let muty = if field.is_const() {
Mutability::Const
} else {
Expand All @@ -407,7 +413,7 @@ impl VarInfo {
None,
kind,
None,
AbsLocation::unknown(),
loc,
)
}

Expand Down

0 comments on commit c514d0d

Please sign in to comment.