mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 12:14:43 +00:00
chore(els): impl hover/jump for type specification
This commit is contained in:
parent
2005d0640d
commit
4137a07b70
10 changed files with 87 additions and 28 deletions
|
@ -551,12 +551,21 @@ 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.name().token(), token)
|
||||
}
|
||||
Signature::Var(var) => self
|
||||
.return_var_info_if_same(&var.ident, var.name().token(), token)
|
||||
.or_else(|| {
|
||||
var.t_spec
|
||||
.as_ref()
|
||||
.and_then(|t_spec| self.get_expr_info(&t_spec.expr, token))
|
||||
}),
|
||||
Signature::Subr(subr) => self
|
||||
.return_var_info_if_same(&subr.ident, subr.name().token(), token)
|
||||
.or_else(|| self.get_params_info(&subr.params, token)),
|
||||
.or_else(|| self.get_params_info(&subr.params, token))
|
||||
.or_else(|| {
|
||||
subr.return_t_spec
|
||||
.as_ref()
|
||||
.and_then(|t_spec| self.get_expr_info(&t_spec.expr, token))
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -3863,7 +3863,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 {
|
||||
|
@ -3909,14 +3909,14 @@ impl SubrSignature {
|
|||
ident: Identifier,
|
||||
bounds: TypeBoundSpecs,
|
||||
params: Params,
|
||||
return_t: Option<TypeSpec>,
|
||||
return_t_spec: Option<TypeSpecWithOp>,
|
||||
) -> Self {
|
||||
Self {
|
||||
decorators,
|
||||
ident,
|
||||
bounds,
|
||||
params,
|
||||
return_t_spec: return_t,
|
||||
return_t_spec,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3933,7 +3933,7 @@ impl SubrSignature {
|
|||
pub struct LambdaSignature {
|
||||
pub bounds: TypeBoundSpecs,
|
||||
pub params: Params,
|
||||
pub return_t_spec: Option<TypeSpec>,
|
||||
pub return_t_spec: Option<TypeSpecWithOp>,
|
||||
}
|
||||
|
||||
impl fmt::Display for LambdaSignature {
|
||||
|
@ -3974,7 +3974,7 @@ impl Locational for LambdaSignature {
|
|||
impl LambdaSignature {
|
||||
pub const fn new(
|
||||
params: Params,
|
||||
return_t_spec: Option<TypeSpec>,
|
||||
return_t_spec: Option<TypeSpecWithOp>,
|
||||
bounds: TypeBoundSpecs,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -4109,7 +4109,7 @@ impl Signature {
|
|||
pub fn t_spec(&self) -> Option<&TypeSpec> {
|
||||
match self {
|
||||
Self::Var(v) => v.t_spec.as_ref().map(|t| &t.t_spec),
|
||||
Self::Subr(c) => c.return_t_spec.as_ref(),
|
||||
Self::Subr(c) => c.return_t_spec.as_ref().map(|t| &t.t_spec),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -252,7 +252,7 @@ impl Parser {
|
|||
subr.ident,
|
||||
subr.bounds,
|
||||
subr.params,
|
||||
Some(tasc.t_spec.t_spec),
|
||||
Some(tasc.t_spec),
|
||||
);
|
||||
Signature::Subr(subr)
|
||||
}
|
||||
|
|
|
@ -454,7 +454,7 @@ impl Desugarer {
|
|||
new
|
||||
}
|
||||
|
||||
fn add_arg_to_match_call(&self, mut previous: Def, def: Def) -> (Call, Option<TypeSpec>) {
|
||||
fn add_arg_to_match_call(&self, mut previous: Def, def: Def) -> (Call, Option<TypeSpecWithOp>) {
|
||||
let op = Token::from_str(TokenKind::FuncArrow, "->");
|
||||
let Expr::Call(mut call) = previous.body.block.remove(0) else { unreachable!() };
|
||||
let Signature::Subr(sig) = def.sig else { unreachable!() };
|
||||
|
@ -484,7 +484,7 @@ impl Desugarer {
|
|||
}
|
||||
|
||||
// TODO: procedural match
|
||||
fn gen_match_call(&self, previous: Def, def: Def) -> (Call, Option<TypeSpec>) {
|
||||
fn gen_match_call(&self, previous: Def, def: Def) -> (Call, Option<TypeSpecWithOp>) {
|
||||
let op = Token::from_str(TokenKind::FuncArrow, "->");
|
||||
let Signature::Subr(prev_sig) = previous.sig else { unreachable!() };
|
||||
let params_len = prev_sig.params.len();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue