fix: improve completion

This commit is contained in:
Shunsuke Shibayama 2023-02-08 20:40:38 +09:00
parent 4571ced013
commit 94a62d22ac
5 changed files with 21 additions and 19 deletions

View file

@ -35,7 +35,7 @@ impl<Checker: BuildRunnable> Server<Checker> {
let prev_token = self.file_cache.get_token_relatively(&uri, pos, -1)?;
if prev_token
.as_ref()
.map(|t| t.kind == TokenKind::Dot)
.map(|t| t.is(TokenKind::Dot) || t.is(TokenKind::DblColon))
.unwrap_or(false)
{
let dot_pos = util::loc_to_pos(prev_token.unwrap().loc()).unwrap();

View file

@ -83,7 +83,7 @@ impl FileCache {
let Some(index) = self.get_token_index(uri, pos)? else {
let tokens = self.get(uri)?.token_stream.as_ref().ok_or("lex error")?;
for token in tokens.iter().rev() {
if !token.is(TokenKind::EOF) && !token.is(TokenKind::Dedent) && !token.is(TokenKind::Newline) {
if !matches!(token.kind, TokenKind::EOF | TokenKind::Dedent | TokenKind::Newline) {
return Ok(Some(token.clone()));
}
}

View file

@ -16,7 +16,6 @@ use erg_common::normalize_path;
use erg_compiler::artifact::BuildRunnable;
use erg_compiler::build_hir::HIRBuilder;
use erg_compiler::context::{Context, ModuleContext};
use erg_compiler::erg_parser::token::TokenKind;
use erg_compiler::hir::HIR;
use erg_compiler::module::{SharedCompilerResource, SharedModuleIndex};
@ -436,22 +435,22 @@ impl<Checker: BuildRunnable> Server<Checker> {
.file_cache
.get_token_relatively(uri, attr_marker_pos, -1)?;
if let Some(token) = maybe_token {
if token.is(TokenKind::Symbol) {
let var_name = token.inspect();
Self::send_log(format!("{} name: {var_name}", line!()))?;
Ok(module.context.get_receiver_ctxs(var_name))
Self::send_log(format!("token: {token}"))?;
let var_name = token.inspect();
let ctxs = module.context.get_receiver_ctxs(var_name);
if let Some(typ) = self
.get_visitor(uri)
.and_then(|visitor| visitor.get_t(&token))
{
Self::send_log(format!("type: {typ}"))?;
let type_ctxs = module
.context
.get_nominal_super_type_ctxs(&typ)
.unwrap_or(vec![]);
Ok([ctxs, type_ctxs].concat())
} else {
Self::send_log(format!("non-name token: {token}"))?;
if let Some(typ) = self
.get_visitor(uri)
.and_then(|visitor| visitor.get_t(&token))
{
let t_name = typ.qual_name();
Self::send_log(format!("type: {t_name}"))?;
Ok(module.context.get_receiver_ctxs(&t_name))
} else {
Ok(vec![])
}
Self::send_log("failed to get the type")?;
Ok(ctxs)
}
} else {
Self::send_log("token not found")?;

View file

@ -19,6 +19,8 @@ pub fn loc_to_range(loc: erg_common::error::Location) -> Option<Range> {
}
pub fn loc_to_pos(loc: erg_common::error::Location) -> Option<Position> {
// FIXME: should `Position::new(loc.ln_begin()? - 1, loc.col_begin()?)`
// but completion doesn't work (because the newline will be included)
let start = Position::new(loc.ln_begin()? - 1, loc.col_begin()? + 1);
Some(start)
}
@ -29,6 +31,7 @@ pub fn pos_in_loc<L: Locational>(loc: &L, pos: Position) -> bool {
let in_lines = (ln_begin..=ln_end).contains(&(pos.line + 1));
if ln_begin == ln_end {
in_lines
// FIXME: .., not ..=
&& (loc.col_begin().unwrap_or(0)..=loc.col_end().unwrap_or(0)).contains(&pos.character)
} else {
in_lines

View file

@ -1753,7 +1753,7 @@ impl Context {
concatenated
}
pub(crate) fn get_nominal_super_type_ctxs<'a>(&'a self, t: &Type) -> Option<Vec<&'a Context>> {
pub fn get_nominal_super_type_ctxs<'a>(&'a self, t: &Type) -> Option<Vec<&'a Context>> {
match t {
Type::FreeVar(fv) if fv.is_linked() => self.get_nominal_super_type_ctxs(&fv.crack()),
Type::FreeVar(fv) => {