chore(els): impl hover/jump for type specification

This commit is contained in:
Shunsuke Shibayama 2023-06-02 10:54:31 +09:00
parent 2005d0640d
commit 4137a07b70
10 changed files with 87 additions and 28 deletions

View file

@ -2865,7 +2865,7 @@ impl PyCodeGenerator {
("_".into(), Params::single(self_param))
};
let bounds = TypeBoundSpecs::empty();
let subr_sig = SubrSignature::new(ident, bounds, params, sig.t_spec().cloned());
let subr_sig = SubrSignature::new(ident, bounds, params, sig.t_spec_with_op().cloned());
let mut attrs = vec![];
match new_first_param.map(|pt| pt.typ()) {
// namedtupleは仕様上::xなどの名前を使えない
@ -2944,7 +2944,7 @@ impl PyCodeGenerator {
let param = NonDefaultParamSignature::new(raw, vi, None);
let params = Params::single(param);
let bounds = TypeBoundSpecs::empty();
let sig = SubrSignature::new(ident, bounds, params, sig.t_spec().cloned());
let sig = SubrSignature::new(ident, bounds, params, sig.t_spec_with_op().cloned());
let arg = PosArg::new(Expr::Accessor(Accessor::private_with_line(
Str::from(param_name),
line,
@ -2956,7 +2956,7 @@ impl PyCodeGenerator {
} else {
let params = Params::empty();
let bounds = TypeBoundSpecs::empty();
let sig = SubrSignature::new(ident, bounds, params, sig.t_spec().cloned());
let sig = SubrSignature::new(ident, bounds, params, sig.t_spec_with_op().cloned());
let call = class_new.call_expr(Args::empty());
let block = Block::new(vec![call]);
let body = DefBody::new(EQUAL, block, DefId(0));

View file

@ -307,7 +307,7 @@ impl Context {
.as_ref()
.map(|subr| ParamTy::Pos(subr.return_t.as_ref().clone()));
match self.instantiate_typespec_full(
t_spec,
&t_spec.t_spec,
opt_decl_t.as_ref(),
&mut tmp_tv_cache,
mode,

View file

@ -988,7 +988,7 @@ impl Context {
let mut dummy_tv_cache = TyVarCache::new(self.level, self);
let spec_t = self
.instantiate_typespec_full(
spec,
&spec.t_spec,
None,
&mut dummy_tv_cache,
PreRegister,

View file

@ -2,7 +2,7 @@ use std::mem;
use erg_common::consts::PYTHON_MODE;
use erg_common::traits::{Locational, Runnable, Stream};
use erg_common::{enum_unwrap, fn_name, log, set, Str};
use erg_common::{enum_unwrap, fn_name, log, set, Str, Triple};
use erg_parser::ast::{self, AscriptionKind, Identifier, VarName, AST};
@ -167,7 +167,24 @@ impl ASTLowerer {
}
ast::Accessor::Attr(attr) => {
let obj = self.fake_lower_expr(*attr.obj)?;
let ident = hir::Identifier::bare(attr.ident);
let mut ident = hir::Identifier::bare(attr.ident);
if let Ok(ctxs) = self
.module
.context
.get_singular_ctxs_by_hir_expr(&obj, &self.module.context)
{
for ctx in ctxs {
if let Triple::Ok(vi) = ctx.rec_get_var_info(
&ident.raw,
AccessKind::Attr,
self.input(),
&self.module.context,
) {
ident.vi = vi;
break;
}
}
}
Ok(obj.attr(ident))
}
other => Err(LowerErrors::from(LowerError::declare_error(
@ -291,7 +308,14 @@ impl ASTLowerer {
ast::Signature::Subr(subr) => {
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);
let ret_t_spec = if let Some(ts) = subr.return_t_spec {
let spec_t = self.module.context.instantiate_typespec(&ts.t_spec)?;
let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
Some(hir::TypeSpecWithOp::new(ts, expr, spec_t))
} else {
None
};
let sig = hir::SubrSignature::new(ident, subr.bounds, params, ret_t_spec);
Ok(hir::Signature::Subr(sig))
}
}

View file

@ -1817,7 +1817,7 @@ pub struct SubrSignature {
pub ident: Identifier,
pub bounds: TypeBoundSpecs,
pub params: Params,
pub return_t_spec: Option<TypeSpec>,
pub return_t_spec: Option<TypeSpecWithOp>,
}
impl NestedDisplay for SubrSignature {
@ -1869,7 +1869,7 @@ impl SubrSignature {
ident: Identifier,
bounds: TypeBoundSpecs,
params: Params,
return_t_spec: Option<TypeSpec>,
return_t_spec: Option<TypeSpecWithOp>,
) -> Self {
Self {
ident,
@ -2014,6 +2014,13 @@ impl Signature {
pub fn t_spec(&self) -> Option<&TypeSpec> {
match self {
Self::Var(v) => v.t_spec.as_ref().map(|t| &t.raw.t_spec),
Self::Subr(s) => s.return_t_spec.as_ref().map(|t| &t.raw.t_spec),
}
}
pub fn t_spec_with_op(&self) -> Option<&TypeSpecWithOp> {
match self {
Self::Var(v) => v.t_spec.as_ref(),
Self::Subr(s) => s.return_t_spec.as_ref(),
}
}

View file

@ -1549,8 +1549,14 @@ impl ASTLowerer {
}
};
let ident = hir::Identifier::new(sig.ident, None, vi);
let sig =
hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
let ret_t_spec = if let Some(ts) = sig.return_t_spec {
let spec_t = self.module.context.instantiate_typespec(&ts.t_spec)?;
let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
Some(hir::TypeSpecWithOp::new(ts, expr, spec_t))
} else {
None
};
let sig = hir::SubrSignature::new(ident, sig.bounds, params, ret_t_spec);
let body = hir::DefBody::new(body.op, block, body.id);
Ok(hir::Def::new(hir::Signature::Subr(sig), body))
}
@ -1569,8 +1575,14 @@ impl ASTLowerer {
}
};
let ident = hir::Identifier::new(sig.ident, None, vi);
let sig =
hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
let ret_t_spec = if let Some(ts) = sig.return_t_spec {
let spec_t = self.module.context.instantiate_typespec(&ts.t_spec)?;
let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
Some(hir::TypeSpecWithOp::new(ts, expr, spec_t))
} else {
None
};
let sig = hir::SubrSignature::new(ident, sig.bounds, params, ret_t_spec);
let block =
hir::Block::new(vec![hir::Expr::Dummy(hir::Dummy::new(vec![]))]);
let body = hir::DefBody::new(body.op, block, body.id);
@ -1594,7 +1606,14 @@ impl ASTLowerer {
.fake_subr_assign(&sig.ident, &sig.decorators, Type::Failure)?;
let block = self.lower_block(body.block)?;
let ident = hir::Identifier::bare(sig.ident);
let sig = hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec);
let ret_t_spec = if let Some(ts) = sig.return_t_spec {
let spec_t = self.module.context.instantiate_typespec(&ts.t_spec)?;
let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
Some(hir::TypeSpecWithOp::new(ts, expr, spec_t))
} else {
None
};
let sig = hir::SubrSignature::new(ident, sig.bounds, params, ret_t_spec);
let body = hir::DefBody::new(body.op, block, body.id);
Ok(hir::Def::new(hir::Signature::Subr(sig), body))
}